Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > Blitz3D > FAQ

FAQ Туториалы и часто задаваемые вопросы

Ответ
 
Опции темы
Старый 04.11.2006, 22:25   #1
НУБ
Бывалый
 
Регистрация: 22.09.2005
Сообщений: 634
Написано 36 полезных сообщений
(для 102 пользователей)
Операции над вершинами и треугольниками в памяти Blitz3D

Для эффективной и максимально быстрой работы с вершинами и треугольниками, операции над ними можно производить непосредственно в памяти из внешних библиотек, не прибегая к встроенным командам блица.

В качестве примера напишем функцию для преобразования всех вершин выбранного сурфейса в глобальную систему координат произвольной Entity, в качастве среды разработки возьмём MSVC++ 6.0.

Для начала нам нужно получить адрес сурфейса(сетки), где хранятся Vertex Buffer и Index Buffer(треугольники).

SurfHandle = GetSurface(model, 1 ) ;хендл(адрес) сурфейса.

(прим. Структуру сурфейса можно посмотреть здесь: http://blitz.pp.ru/forum/showthread.php?s=&threadid=203)

Vertex Buffer лежит по смещению (SurfHandle + 28байт), Index Buffer - (SurfHandle + 44байта).

Для простоты работы с вершинами можно создать специальную структуру, с помощью которой мы будем обращаться к параметрам вершины:


typedef struct _BBVERTEX
{
float x,y,z;
float nx,ny,nz;
char a,r,g,b;
float u0,v0;
float u1,v1;
char i1,i2,i3,i4;
float w1,w2,w3,w4;

} BBVERTEX, *LPBBVERTEX;


Точно также можно сделать и для треугольников:


typedef struct _BBTRIANGE
{
unsigned short a,b,c;

} BBTRIANGE, *LPBBTRIANGE;


(прим. Треугольник - это последовательность 3-х индексов в IndexBuffer соответственно)

Для получения положения Entity (поворот, размер, позиция), воспользуемся её матрицей трансформации.
Глобальная матрица хранится по смещению (SurfHandle + 216байт), таже матрица, но с учётом Tween(если используется), хранится по адресу (SurfHandle + 516байт).

(прим. В спецификации DirectX используются матрицы размерностью 4х4, но для пространственных преобразований достаточно матрицы 3х4, она и хранится в структуре Entity в блице)

Получение матрицы:


float	EMatrix11= *(Entity+44);
float	EMatrix12= *(Entity+45);
float	EMatrix13= *(Entity+46);

float	EMatrix21= *(Entity+47);
float	EMatrix22= *(Entity+48);
float	EMatrix23= *(Entity+49);

float	EMatrix31= *(Entity+50);
float	EMatrix32= *(Entity+51);
float	EMatrix33= *(Entity+52);

float	EMatrix41= *(Entity+53);
float	EMatrix42= *(Entity+54);
float	EMatrix43= *(Entity+55);


(прим. В С++ значение смещения для указателей учитывается в соответствии с их типом, например, если используется тип Float(4байта), то смещение на 40 байт будет указано как +10)

Для преобразования координат вершины, нужно перемножить их на матрицу:


//координаты исходной сетки.
x=SrcVertexBuffer[vertex].x;
y=SrcVertexBuffer[vertex].y;
z=SrcVertexBuffer[vertex].z;

//преобразованные координаты.
DestVertexBuffer [vertex].x = EMatrix11*x + EMatrix12*y + EMatrix13*z + EMatrix41;
DestVertexBuffer [vertex].y = EMatrix21*x + EMatrix22*y + EMatrix23*z + EMatrix42;
DestVertexBuffer [vertex].z = EMatrix31*x + EMatrix32*y + EMatrix33*z + EMatrix43;


(Прим. Хочу предупредить, что в матрице значения углов будут инвертированными, это нужно учесть ;) )

Количество вершин можно получить так:

int VertexCount = ( *(surfaceSrc+8) - *(surfaceSrc+7) )/64;
(прим. 64 - количество байт на одну вершину)

Цикл перебора вершин будет выглядеть так:


for (int vertex = 0; vertex<VertexCount; vertex++)
{
x=SrcVertexBuffer[vertex].x;
y=SrcVertexBuffer[vertex].y;
z=SrcVertexBuffer[vertex].z;

DestVertexBuffer [vertex].x = EMatrix11*x + EMatrix12*y + EMatrix13*z + EMatrix41;
DestVertexBuffer [vertex].y = EMatrix21*x + EMatrix22*y + EMatrix23*z + EMatrix42;
DestVertexBuffer [vertex].z = EMatrix31*x + EMatrix32*y + EMatrix33*z + EMatrix43;
}


Таким образом Мы можем вертеть сетку в соответствии с позицией любой Entity :)

(Прим. При изменении координат вершин мы изменяем размер всей сетки, но блиц проверяет её видимость по старому размеру, поэтому корректнее также изменять и параметры ограничивающего бокса(Bounding Box) - см. структуру меша)

Полный код функции:


BBDECL void TransformSurfaceToMatrix( unsigned int *surfaceSrc, unsigned int *surfaceDest, float *Entity )

{
LPBBVERTEX SrcVertexBuffer, DestVertexBuffer ;

float x,y,z;

float	EMatrix11= *(Entity+44);
float	EMatrix12= *(Entity+45);
float	EMatrix13= *(Entity+46);

float	EMatrix21= *(Entity+47);
float	EMatrix22= *(Entity+48);
float	EMatrix23= *(Entity+49);

float	EMatrix31= *(Entity+50);
float	EMatrix32= *(Entity+51);
float	EMatrix33= *(Entity+52);

float	EMatrix41= *(Entity+53);
float	EMatrix42= *(Entity+54);
float	EMatrix43= *(Entity+55);

SrcVertexBuffer	 = (struct _BBVERTEX *)*(surfaceSrc +7); //Адрес начала вершинного буфера исходной сетки
DestVertexBuffer = (struct _BBVERTEX *)*(surfaceDest+7); //Адрес начала вершинного буфера 
//трансформируемой сетки

*(surfaceDest+16)=0; //Обнуление этого флага означает изменение вертекс буфера, после чего
// он будет передан видеокарте

int VertexCount = ( *(surfaceSrc+8) - *(surfaceSrc+7) )/64; //Количество вершин в сетке

for (int vertex = 0; vertex<VertexCount; vertex++)
{
x=SrcVertexBuffer[vertex].x;
y=SrcVertexBuffer[vertex].y;
z=SrcVertexBuffer[vertex].z;

// Здесь мы производим перемножение координат вершины исходной сетки на матрицу
// и запись результата в изменяемую сетку
DestVertexBuffer [vertex].x = EMatrix11*x + EMatrix12*y + EMatrix13*z + EMatrix41;
DestVertexBuffer [vertex].y = EMatrix21*x + EMatrix22*y + EMatrix23*z + EMatrix42;
DestVertexBuffer [vertex].z = EMatrix31*x + EMatrix32*y + EMatrix33*z + EMatrix43;
}

}


Пример к статье можно найти здесь: http://andreyman.ucoz.ru/VertexSample.rar


http://andreyman.ucoz.ru/publ/1-1-0-1
http://andreyman.ucoz.ru/blog/2006-11-04-2
(Offline)
 
Ответить с цитированием
Старый 05.11.2006, 00:55   #2
jimon
 
Сообщений: n/a
Re: Операции над вершинами и треугольниками в памяти Blitz3D

интересная инфа ...
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
утечка памяти!? Coks 3D-программирование 9 09.01.2010 21:18
Булевые операции с многоугольниками SBJoker Алгоритмика 4 24.02.2009 16:16
J2me и операции над битами? Pietr79 JAVA Micro Edition 2 14.09.2008 19:37
Булевы операции с фигурами ISKATEL 3D-программирование 3 04.05.2007 02:50
key операции CRACK 3D-программирование 2 02.03.2007 16:00


Часовой пояс GMT +4, время: 13:42.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com