В граве, если кто обратил внимание, пристутсвует какая-то физика. Т.е. при попадании ракеты в стену, стена рушится. Все это легко осуществить встроенными в XNA средствами. Я сам долго над этим возился, может кому из новичков поможет. А кто-нибудь из “старичков” улучшит пример(собственно поэтому и выкладываю, сам я че то не силен в математике, если кому не трудно – сделайте доброе дело). Как вы знаете, (или не знаете) в XNA есть встроенный класс – Box. С ним можно делать кое какие вещи, например, проверка на столкновения и т.д. Что бы создать его достаточно всего два параметра, координаты двух точек, самой дальней от начала оси координат и самой ближней. К сожалению в этой простоте и кроется подвох – создавать боксы можно только параллельными этим самым осям координат (т.е. такими какими они есть в Grave, поэтому там нет косых сооружений). Я сначала пробовал конечно вручную создавать все эти боксы, но мягко говоря “подустал”, вонзникла мысль что не барское (человечье) это дело, пусть этим РС занимается на то у него и голова железная (или кремниевая). В общем путем нехитрых усилий я создал функцию. Что делает человек – в редакторе 3D создает уровень. Затем, при его визуализации, передает все полученные из него меши в функцию, заодно с мировыми матрицами, которые передает в шейдер для отрисовки. Как результат получает бокс ровно вокруг этого самого меша (если конечно ничего не напутал с матрицами). Советую создать массив боксов и в него заносить все результаты, кроме того, боксы можно, конечно, создавать каждый раз при отрисовке, но желательно делать это один раз при инициализации. А вот проверять на столкновения, наоборот, советую почаще, хотя все конечно зависит от реализации. Кому не интересно, может не разбирать, функция прекрасно работает сама. Только успевай вызывать.
BoundingBox box(ModelMesh mesh, Matrix matrix){VertexPositionColor[] vector =new VertexPositionColor[mesh.VertexBuffer.SizeInBytes/ VertexPositionColor.SizeInBytes];// создаем массив вершин, в который будут // записанны все вершины меша.
Тут важно задать размер этого массива. Древний и самый точный метод, которым до сих пор пользуются гадалки хорош, но в данном случае не помог. Путем другого, весьма похожего, “метода научного тыка”, я сделал следующую реализацию.
// ответственно заявляю – работает. Почему сам не знаю, но чувствую – // делать надо так mesh.VertexBuffer.GetData(vector);// тут мы лихо загоняем все вершин меша в созданный нами массив и в дальнейшем работаем уже с ним Vector3 max =new Vector3();//как было сказано, нам достаточно Vector3 min =new Vector3();//всего двух точек for(int i =0; i < vector.Length; i++){vector[i].Position= Vector3.Transform(vector[i].Position, matrix);//берем из нашего массива только координаты, т.е. позицию // не забываем перемножать на матрицу, что бы все вершины были на месте // и считались не так как в модели, а так как в нашем уютном // трехмерном мире if(i ==0){max = vector[i].Position; min = vector[i].Position;// при первом проходе и max и min будут равны нулю // и если весь меш находится по ту сторону нуля (т.е. меньше его) // наши вершины автоматически становятся самыми большими // и бокс будет образован вокруг них // мы этого не допустим и присвоим им обязательно значения // а дальше, точнее ниже, все идет по накатаной, само собой // просто сравниваются все значения и остаются только наибольшие и наименьшие }if(max.Z< vector[i].Position.Z)max.Z= vector[i].Position.Z;if(min.Z> vector[i].Position.Z)min.Z= vector[i].Position.Z;if(max.Y< vector[i].Position.Y)max.Y= vector[i].Position.Y;if(min.Y> vector[i].Position.Y)min.Y= vector[i].Position.Y;if(max.X< vector[i].Position.X)max.X= vector[i].Position.X;if(min.X> vector[i].Position.X)min.X= vector[i].Position.X;}returnnew BoundingBox(min, max);//итог: дали меш и матрицу, // получили бокс, как и обещал. }
Кому не нравится, пусть придумает лучше, с удовольствием посмотрю сам на лучшую реализацию. Я лишь задал направление, кто способен сделать лучше, пусть делает. Очень хотелось бы что бы кто нибудь взялся за реализацию боксов не параллельных осям координат. Тут нужно будет писать свой класс. Я бы написал, но мои попытки навели на мысль,что без знания математики (может быть даже высшей) тут не обойтись. Как я понимаю достаточно будет всего трех вершин. Ну а проверку столкновения написать не так уж и сложно. Ну и сам алгоритм нахождения дальней или ближней вершины, может тоже можно улучшить, я лично ничего лучше не придумал.
662 Прочтений • [BOX-ы и физика] [08.08.2012] [Комментариев: 0]