25.06.2004, 17:02 (Сообщение последний раз редактировалось: 27.06.2004, 20:12 ELF.)
Решил тут немного поразбираться с форматом CAM.
Узнал, что у файла CAM нет заголовка, он разбит на поля по 36 байт. Скорее всего все поля являются float'ами...
Скорее всего буду сейчас над ними баловаться...
-------------
Урезал файл mainmenu.cam до 36 байт. Работает нормально! :blink:
Скорее всего Нивальцы опять что-то хотели, но недоделали...
Узнал, что первые два поля (из девяти в одном блоке) камеру не трогают, остальные её крутят как-то непонятно... может быть, даже по кругу. :ph34r:
-------------
Итак, нулевое и первое поля ещё не известны.
Поле 2: Смещение на восток;
Поле 3: Смещение на север;
Поле 4: Смещение в небо.
Всё-таки в этих полях перемещение идёт по прямой.
--------------
Поля 5,6,7,8 поворачивают камеру. Но вот делают они это очень не хорошо! :angry:
Очень странная тректория поворота камеры.
Но всё-таки смог немного разобраться: Поля 7 и 8 делаю поворот в одну сторону (при увеличении камера поворачивается к небу, если смотрела прямо). Если записать в поле 7 ноль, то камера будет смотреть в небо, а если записать в поле 8 ноль, а в поле 7 число (0>xxx>1), то камера будет смотреть на землю. Чтобы камера смотрела прямо, желательно в поле 7 поставить -1, а в поле 8 поставить 1 (скорее всего камера становится в разницу между этими значениями). Поля 5 и 6 ещё кривее предыдущих. Они тоже работают на пару. Если увеличивать эти поля, причём сохранять их равными, то камера будет проворачиваться набок против часовой стрелки. А вот если значения этих полей увеличивать, но при этом сохранять их равными с противоположными знаками, то камера будет поворачиваться, как обычные юниты поворачиваются, только при увеличении значений резко падает чуствительность камеры и её начинает косить (это дело выравнивается подборкой мелкой разницы между абсолютными значениями полей).
Хух, я бы лучше понял логику поворота камеры, скорее всего, если бы знал, как обычно в играх реализую работу с камерой. А так вот приходится вертеться.
Смысл первых двух полей я так и не понял. Знаю, что второе поле часто бывает отключено (FF FF FF FF), а в первом гигантское значения записаны, но в разумных пределах для float - скорее всего это ID, или что-то типа номерка... :unsure:
Пока на этом работы с форматом CAM останавливаю. Мне удобнее всего их было менять спомощью ArtMoney 7.08 - она файлы править умеет, причём позволяет разбивать файл на поля нужно типа.
06.07.2004, 12:48 (Сообщение последний раз редактировалось: 06.07.2004, 22:55 Jet.)
Цитата:Хух, я бы лучше понял логику поворота камеры, скорее всего, если бы знал, как обычно в играх реализую работу с камерой. А так вот приходится вертеться
Ключевое слово здесь - кватернионы.В формате cam все сделано четко и логично.Не следует оправдывать собственное незнание кривосью Нивала.
Возьми самый большой файл cam (не помню уже его название).
На нем удобно проводить изучение.
4 байта - время камеры (если записей положения больше чем 1)
4 байта - хз...не помню что за поле
3 блока по 4 байта - координаты x,y,z
4 блока по 4 байта - кватернион поворота камеры
итого 9 блоков по 4 байта и есть наши 36 байт на одну запись положения.
Теперь у меня в плане работ будет ещё и изучение кватернионов (которые, как я понял, относятся к фракталам и комплексным числам, о которых я ничего не знаю).
ALtair, прости, просто я грубо написал, я имел ввиду, что кватернионы относятся к фракталам и комплексным числам по сложности, т.к. всё это высшая математика.
Вообще кватернион в данном случае уж точно не координаты описывает (это я сам на собственной шкуре проверял), а именно поворот камеры он описывает.
В трехмерной геометрии поворот задается координатами вектора поворота, если не ошибаюсь. А вообще в 3Д Графике по идее поворот должен задаваться матрицей.
Duty is everything, the greatest of joys, the deepest of sorrows.
Ладно, просто скажу, что хотел вообще придумать алгоритм, который, имея расположение камеры (x,y,z) и точку, куда она должна смотреть, соответственно её повернёт. :unsure:
Я вот уже научился немного делать эти кватернионы. Теперь у меня другая проблема, попробую объяснить её суть:
Итак, мы имеет две 3D-точки (x,y,z). Нам нужно сделать так, чтобы камера оказалась в первой точке и смотрела во вторую. Первое, что мне пришло на ум, что нужно задать ось вращения от первой точке ко второй. Эта ось задаётся вектором:
VectorAxis ( x2-x1, y2-y1, z2-z1 )
, где x1,y1,z1 - Первая точка; x2,y2,z2 - Вторая.
Чтобы переделать ось (Axis) + угол (Angle) вращения в кватернион, нужно провести, как мне кажется, известные рассчёты.
Предварительно нужно вектор, который описывает ось сделать единичным - разделить все его компоненты на его же длину. А затем вот:
Код:
w = cos(Angle/2)
x = AxisX * sin(Angle/2)
y = AxisY * sin(Angle/2)
z = AxisZ * sin(Angle/2)
Как я понял, в ПЗ кватернион записан так: Quaternion {x, y, z, w}
Просто, на сайтах, которые я показал, написано наоборот.
Проблема заключается в том, что если ось вращения будет пересекать обе 3D-точки (наши), то камера никогда не будет смотреть во вторую точку. Решение этой проблемы я нашёл в том, чтобы развернуть ось на 90% и тогда при определённом углу вращения камера должна будет смотреть во вторую точку. Вот только как повернуть ось на 90%????
Может я вообще не в ту степь лезу? Просто очень хочется с делом этим разобраться.
ALtair, а сможешь рассчитать матрицу3x3 поворота по начальной и конечной точке? Просто я нашёл алгоритм, который переводит матрицу в кватернион, но вот теперь задать матрицу проблема. Как ни пытаюсь не пойму. Там в матрице целых три вектора задавать надо, а я могу только один получить по начальной и конечной точкам. Как остальные два вектора найти?
Опять же, пишу по памяти, вполне возможно, что не прав. При простых преобразованиях (поворот, смещение и т.д.), задаваемых матрицами, в самой матрице используется только 4 ячейки. Конфигурация используемых ячеек и функции, подставляемые в ячейки, тебе придется поискать в инете.
Duty is everything, the greatest of joys, the deepest of sorrows.
Вижу что это давно обсуждалось сам занят разработкой cam едитора , но у меня возникли нсколько проблем ( я пишу на Blitz3D ибо на нем 3д делать просто , следственно у меня 3д cam едитор ) вообщем при чтении самого большего файла с камерами получается деформированный овал из камер ( я так предполагаю это границы камеры на базе ) но они расположены перпендикулярно плоскости , меня это почемуто настораживает . возможно в кам файле координаты хранятся не в прямом порядке ? Ну и насчет кватернионов , опятьже непонятно как они хранятся XYZW или WXYZ или еще как нибудь .
Кому интересно вот библа , для Blitz3D Которая переводит кватернионы в углы эйлера и обратно ( тут нарисовывается проблема в том что в углах эйлера важены не только координаты угла , но и то в каком порядке поворачивается обьект )
Вот код :
Код:
; Quat.bb : v1.0 : 15/11/02
; A tutorial on how to use this file is at http://www.dscho.co.uk/blitz/tutorials/quaternions.shtml
; Types
Type Rotation
Field pitch#, yaw#, roll#
End Type
Type Quat
Field w#, x#, y#, z#
End Type
; Change these constants if you notice slips in accuracy
Const QuatToEulerAccuracy# = 0.001
Const QuatSlerpAccuracy# = 0.0001
; convert a Rotation to a Quat
Function EulerToQuat(out.Quat, src.Rotation)
; NB roll is inverted due to change in handedness of coordinate systems
Local cr# = Cos(-srcroll/2)
Local cp# = Cos(srcpitch/2)
Local cy# = Cos(srcyaw/2)
Local sr# = Sin(-srcroll/2)
Local sp# = Sin(srcpitch/2)
Local sy# = Sin(srcyaw/2)
; These variables are only here to cut down on the number of multiplications
Local cpcy# = cp * cy
Local spsy# = sp * sy
Local spcy# = sp * cy
Local cpsy# = cp * sy
; Generate the output quat
outw = cr * cpcy + sr * spsy
outx = sr * cpcy - cr * spsy
outy = cr * spcy + sr * cpsy
outz = cr * cpsy - sr * spcy
End Function
; convert a Quat to a Rotation
Function QuatToEuler(out.Rotation, src.Quat)
Local sint#, cost#, sinv#, cosv#, sinf#, cosf#
Local cost_temp#
; Generate the output rotation
outroll = -ATan2(sinv, cosv); inverted due to change in handedness of coordinate system
outpitch = ATan2(sint, cost)
outyaw = ATan2(sinf, cosf)
End Function
; use this to interpolate between quaternions
Function QuatSlerp(res.Quat, start.Quat, fin.Quat, t#)
Local scaler_w#, scaler_x#, scaler_y#, scaler_z#
Local omega#, cosom#, sinom#, scale0#, scale1#
; result will be the same rotation as doing q1 then q2 (order matters!)
Function MultiplyQuat(result.Quat, q1.Quat, q2.Quat)
Local a#, b#, c#, d#, e#, f#, g#, h#
a = (q1w + q1x) * (q2w + q2x)
b = (q1z - q1y) * (q2y - q2z)
c = (q1w - q1x) * (q2y + q2z)
d = (q1y + q1z) * (q2w - q2x)
e = (q1x + q1z) * (q2x + q2y)
f = (q1x - q1z) * (q2x - q2y)
g = (q1w + q1y) * (q2w - q2z)
h = (q1w - q1y) * (q2w + q2z)
resultw = b + (-e - f + g + h) / 2
resultx = a - ( e + f + g + h) / 2
resulty = c + ( e - f + g - h) / 2
resultz = d + ( e - f - g + h) / 2
End Function
; convenience function to fill in a rotation structure
Function FillRotation(r.Rotation, pitch#, yaw#, roll#)
rpitch = pitch
ryaw = yaw
rroll = roll
End Function
PS Думаю понять его будет нетрудно так как это проктически обычный бейзик .
Забыл в предыдущем посте написать ник вообщем если сможете чем помочь или может я смогу вам чем помочь вот мои контакты
ICQ 272529694
mail conan_fedr_666@mail.ru
MSN conan_fedr_666@mail.ru
Вообщем вотЪ мне нужна помощь , мой кам вьюер очень глючный , несчитая того что я возможно неправельно пересчитываю координаты , он еще почемуто все камы кроме самого большего несовсем правельно отображает в плане того что видна лиш одна камер , я незнаю изза чего это хотя сбоку в меню отображаются что камер 9 или больше в зависимости от файла , очень странное явление .
Вообщем вот мой исходник , тут используются либы quaternions опубликованная выше и XUI2 либа интерфейса . Прошу вас посмотреть и порекомендовать все что можно от координат и угла до того как правельнее организовать интерфейс и глючащих камер . Также я прилагаю архив в котором скомпилиная прога со всем необходимым , извините правда она неудобная очень я ее очень мало писал буквально пару часов . Чтобы подгрузить в нее какойнить файл нада в блокнотике который идет с ней написать имя этого файла с расширением ессесно cam , положить этот файл в папку с прогой и запустить программу , да еще необходим DirectX не меньше 7 версии . Вот все вообщем
Исходник :
Код:
; Включения
Include "XUI2.bb"
Include "Quaternions.bb"
; Глобальные переменные
Global tool_window%
Global tool_label_name%,tool_group_actions%
Global tool_group_zap%,tool_group_coords%,tool_list_nodes%
Global camFile%,camPiv%
; Тип записи в ListView'ве записей камеры
Type TZapNode
Field Name$
Field Node%
Field Entity%
End Type
; Тип записи камеры
Type TCamNode
Field Id$
Field Hz%
Field PosX#
Field PosY#
Field PosZ#
Field Rot.Rotation
Field CamMarker%
End Type
; Инициализация графического режима
Graphics3D 800,600,32,2
SetBuffer BackBuffer()
HidePointer()
AppTitle(APP_TITLE)
If KeyDown(200) Then MoveEntity Camera,0,0,1
If KeyDown(208) Then MoveEntity Camera,0,0,-1
If KeyDown(203) Then TurnEntity Camera,0,1,0
If KeyDown(205) Then TurnEntity Camera,0,-1,0
If KeyDown(17) Then TurnEntity Camera,-1,0,0
If KeyDown(31) Then TurnEntity Camera,1,0,0
UseCamera()
UpdateWorld
;WireFrame 1
RenderWorld
XUI2_Update()
;------------------------------
If MouseDown(1) Then ClickedEntity = CameraPick(Camera,MouseX(),MouseY())
For CN.TCamNode = Each TCamNode
If CNCamMarker = ClickedEntity
info_pos$ = CNPosX + " " + CNPosY + " " + CNPosZ
info_rot$ = CNRotPitch + " " + CNRotYaw + " " + CNRotRoll
info_time$ = CNId
Exit
EndIf
Next
Text 220,20,"Mouse X : "+MouseX()+" Mouse Y : "+MouseY()
Text 220,30,"Picked Entity : "+PickedEntity()
Text 220,40,"Info : Position : "+info_pos
Text 220,50," Rotation : "+info_rot
Text 220,60," Time : "+info_time
If KeyDown(1) Exit
Flip
Forever
; Функция создания интерфейса
Function CreateInterface()
; Окно инструментов
tool_window = XUI2_Window(0,0,200,600,"-$[Tools]$-","",0,1+4)
tool_group_coords = XUI2_GroupBox(tool_window,10,230,180,250,"Coordinates",0,0)
tool_group_actions = XUI2_GroupBox(tool_window,10,480,180,110,"Actions",0,0)
End Function
; Функция чтения cam файла
Function ReadCam(filename$)
Local SizFile%
camFile = OpenFile(filename)
SizFile = FileSize(filename)
For i = 1 To SizFile / 36
CamNode.TCamNode = New TCamNode
ZapNode.TZapNode = New TZapNode
CamNodeRot.Rotation = New Rotation
Quatr.Quat = New Quat
CamNodeId = FRead()
CamNodeHz = IRead()
CamNodePosX = FRead()
CamNodePosY = FRead()
CamNodePosZ = FRead()
Quatrx = FRead()
Quatry = FRead()
Quatrz = FRead()
Quatrw = FRead()
ZapNodeName = "Запись "+i
ZapNodeNode = XUI2_ListItem(tool_list_nodes,ZapNodeName)
ZapNodeEntity = CamNodeCamMarker
;Delete Quatr
;Delete CamNode
Next
End Function
; Функция чтения float'a
Function FRead#()
Return ReadFloat(camFile)
End Function
; Функция чтения int'a
Function IRead%()
Return ReadInt(camFile)
End Function
Function UseCamera()
If MouseDown(1) And KeyDown(56)
TurnEntity Camera, MouseYSpeed(),0,0
TurnEntity Camera, 0,-MouseXSpeed(),0,1
;MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
EndIf
If MouseZSpeed() = 1
MoveEntity Camera,0,0,-3
EndIf
If MouseZSpeed() = -1
MoveEntity Camera,0,0,3
EndIf
End Function
Опять забыл написать кнопки для управления :
W - поворот камеры вверх
S - поворот камеры вниз
Up - Передвежение камеры вперед
Down - Передвежение камеры назад
Left - поворот камеры в лево
Right - поворот камеры в право
Alt + Left Mouse Button - Произвольное вращение камеры
2ELF
"Quaternion {x, y, z, w}" - не верно! Всё работает на WXYZ-настройках. Проблемма редактора камов полностью решена вчера - 18 фефраля 2006 года, да будет памятен этот день %) И спасибо некоторым личностям, которые сильно помогли это сделать.
PS: Из скрина видно, что камера настроена как надо
Снайп это камедитор вопервых ГГшный , вовторых он работает под ГГшным мини редактором . В третьих я хочу забахать свой редактор что у всех был редатор ане только у вас .
Руки есть?
Комп в порядке?
Формат кама известен?
Формулы рабочие есть?
Кватерион считать умеем?
С 3-д программингом знаком?
Буфер данных обрабатывать умеешь?
--------------------------------------------------?
Так что орать на Калбаса, если ты и сам можешь?
А если не можешь сам - так что винить в этом других?
"Но тебе то пох должно быть =)"
По себе людей не судят. Я вот написал там маленький списочек вопросов. Вот пусть тот, кто намеревается сделать эдитор ответит отрицательно хоть на 1 вопрос до разделителя - тогда и будем разбираться. А пока - вперёд и с песней
02.03.2006, 15:47 (Сообщение последний раз редактировалось: 02.03.2006, 15:49 ConanFedr.)
Я непонял чо тут все на меня наезжают ?
У меня тоже есть camEditor уже рабочий только недоделаный еще .
Ну раз вы меня так благадарите у меня вся охота работать отпадает ...
2Jack
Мне интересно кому ты это сказал ?
PS Вообщето когда на когото наезжают на форуме принято писать 2ник_пациента