Blitz3d - Чтение данных, построение моделей

Операторы READ и DATA
Часто бывает так, что нужно переработать в цикле много однородных данных. Для этого существуют операторы READ и DATA. Оператор READ читает значения задаваемых переменных из списка DATA. Синтаксис:

READ переменная1, переменная2, ...
DATA значение1, значение2, ...

Наберем небольшую программу:

FOR n = 1 TO 5
 READ a
 PRINT a
NEXT
DATA 1, 10, 19, 125, 563

Команда “READ a” читает одно значение из списка DATA и заносит его в переменную “a”, затем команда “PRINT a” выводит переменную a на экран. В цикле этот процесс происходит 5 раз. Еще можно читать строки, а также писать в операторе несколько переменных через запятую. В операторе READ важно помнить, какой тип данных вы считываете.

Программа, выводящая фигуру из сфер, считывая их координаты
Фото
Инициализируем трехмерную сцену:

GRAPHICS3D 640,480
cam = CREATECAMERA()
l = CREATELIGHT()

Задаем цикл  из 8 повторений:
FOR n = 1 TO 8

Создаем сферу:
 a = CREATESPHERE()

Читаем два значения  и заносим их  в две переменные дробного типа:
 READ x#, y#

Помещаем созданную сферу  в точку, заданную считанными переменными:
 POSITIONENTITY a, x#, y#, 5

Закрываем цикл  и выводим сцену  на экран:
NEXT
RENDERWORLD
FLIP
WAITKEY

Это данные для оператора READ - восемь раз по два значения
DATA -1.5, 2, -1, 3, 0, 3.5, 1, 3, 1.5, 2, 1, 1, 0, 0, 0, -2

Построение трехмерных фигур по треугольникам

До сих пор мы строили трехмерные сцены из объемных фигур. Но, во многих случаях требуется построить трехмерный объект, который формой отличается от них (взять хотя бы усеченный конус). Для этого в Blitz3D существуют команды построения объектов по элементарным частям - треугольникам. Сначала нужно создать пустую фигуру:

a = CREATEMESH([род])

Эта фигура состоит из поверхностей, каждая из которых имеет свои параметры (текстуру, цвет и т. д.). Поэтому, далее мы создаем поверхность для заданной фигуры:

a = CREATESURFACE(фигура)

Теперь можно добавлять к ней треугольники. Для этого, вначале, нужно найти координаты вершин и внести их в поверхность. Первая введенная вершина имеет индекс 0, следующая - 1 и т. д. Это делается с помощью команды:

ADDVERTEX поверхность, x, y, z, u, v

x, y, z – координаты вершины в пространстве, u, v – координаты на текстуре. Текстурные координаты нужны, чтобы правильно наложить текстуру на объект – они задают соответствие между вершинами в пространстве и точками двумерного рисунка текстуры. Текстура зациклена, то есть бесконечно простирается во все стороны, повторяясь, как плитки паркета. Координаты u = 0 и v = 0 задают угол такой плитки, а u = 0.5 и v = 0.5 – середину. Таким образом, длина “плитки” текстуры по вертикали и горизонтали равна 1ед независимо от ее разрешения.
Следующий шаг – задание самих треугольников. Они задаются командой:

ADDTRIANGLE поверхность, вершина1, вершина2, вершина3

Вершины задаются индексами. Необходимо отметить, что на самом деле такой треугольник имеет только одну сторону. Представим, что он спроецирован на экран. Треугольник изображается тогда, когда его вершины расположены в порядке по часовой стрелке – это значит, он повернут видимой стороной к камере. Если же вершины треугольника расположены против часовой стрелки, значит, он невидим в данный момент и изображать его не нужно. Для обеспечения корректного освещения предназначена следующая команда:

UPDATENORMALS фигура

Создание модели меча

Сначала полезно построить чертеж и найти координаты вершин.
ФотоФото
Создаем заголовок:

GRAPHICS3D 640,480

cam = CREATECAMERA()
POSITIONENTITY cam, 0, 0, -30
l = CREATELIGHT()
ROTATEENTITY l, 0, 45, 45

Загрузим текстуры:

wood = LOADTEXTURE("c:\media\wood.jpg")
steel = LOADTEXTURE("c:\media\steel.jpg",1 + 8 + 64)

Дополнительный параметр во второй строке означает то, что текстура является сферической картой отражений. Это особый тип текстуры, который создает иллюзию зеркальности объекта. Создаем две пустые фигуры и накладываем на них текстуры steel (сталь) и wood (дерево):

m1 = CREATEMESH()
ENTITYTEXTURE m1, steel
m2 = CREATEMESH(m1)
ENTITYTEXTURE m2, wood

Так как порядок действий для оформления фигур один и тот же, а в программе необходимо создать две фигуры, то удобнее будет сделать это в цикле. Оператор IF-THEN задает первую фигуру для оформления в первом шаге цикла, а вторую – во втором.

FOR n=1 TO 2
 IF n = 1 THEN
  m = m1
 ELSE
  m = m2
 END IF

Создаем поверхность, привязанную  к фигуре:
 s = CREATESURFACE(m)

Считываем количество вершин:
 READ vq

Цикл  по всем вершинам:
 FOR nn = 1 TO vq

Считываем координаты вершины:
  READ x#, y#, z#

Добавляем вершину  к поверхности (координаты текстуры возьмем случайные)  и закрываем цикл:
  ADDVERTEX s, x#, y#, z#, RND(1), RND(1)
 NEXT

Считываем кол-во треугольников
 READ tq

Цикл  по всем треугольникам:
 FOR nn = 1 TO tq

Считываем индексы вершин:
  READ v1, v2, v3

Добавляем треугольник, закрываем цикл:
  ADDTRIANGLE s, v1, v2, v3
 NEXT

Обеспечение корректного освещения:
 UPDATENORMALS m

NEXT

Теперь вернемся к основной программе. Создадим две фигуры с адресами m1 и m2 и текстурами steel и wood. Обратите внимание на то, что родительский объект фигуры m1 равен 0, то есть не существует.

m1 = READMESH(0, steel)
m2 = READMESH (m1, wood)

Создадим ручку меча – цилиндр:
cyl = CREATECYLINDER(20, 1, m1)
POSITIONENTITY cyl, 0, -3, 0
SCALEENTITY cyl, 1, 2, 1
ENTITYTEXTURE cyl, wood

Перекладина гарды меча:
cube = CREATECUBE(m1)
POSITIONENTITY cube, 0, -0.5, 0
SCALEENTITY cube, 3, 0.5, 1
ENTITYTEXTURE cube, wood

Далее идет цикл  с командами управления вращением меча  с клавиатуры:
REPEAT
 IF KEYDOWN(200) THEN xa = xa + 1
 IF KEYDOWN(208) THEN xa = xa - 1
 IF KEYDOWN(203) THEN ya = ya + 1
 IF KEYDOWN(205) THEN ya = ya - 1
 ROTATEENTITY m1, xa, ya, 0
 IF KEYDOWN(1) THEN EXIT
 RENDERWORLD
 FLIP
FOREVER

Данные рекомендуется найти по чертежу, привлекая к поиску учеников.

Данные (9 вершин лезвия):
DATA 9
DATA -2, 0, 0
DATA 0, 0, -0.5
DATA 2, 0, 0
DATA 0, 0, 0.5
DATA -2, 20, 0
DATA 0, 19, -0.5
DATA 2, 20, 0
DATA 0, 19, 0.5
DATA 0, 22, 0

12 треугольников лезвия:
DATA 12
DATA 0, 4, 1
DATA 4, 5, 1
DATA 4, 8, 5
DATA 8, 6, 5
DATA 5, 6, 2
DATA 5, 2, 1
DATA 0, 3, 4
DATA 3, 7, 4
DATA 3, 2, 7
DATA 2, 6, 7
DATA 7, 8, 4
DATA 7, 6, 8

10 вершин концов гарды:
DATA 10
DATA -5, -2, 0
DATA -3, 0, -1
DATA 3, 0, -1
DATA 5, -2, 0
DATA 3, -1, -1
DATA -3, -1, -1
DATA -3, 0, 1
DATA 3, 0, 1
DATA 3, -1, 1
DATA -3, -1, 1

8 треугольников концов гарды:
DATA 8
DATA 0, 1, 5
DATA 0, 9, 6
DATA 0, 6, 1
DATA 0, 5, 9
DATA 4, 3, 8
DATA 2, 3, 4
DATA 7, 3, 2
DATA 8, 3, 7