Формат Cam
#1
Решил тут немного поразбираться с форматом CAM.
Узнал, что у файла CAM нет заголовка, он разбит на поля по 36 байт. Скорее всего все поля являются float'ами...

Скорее всего буду сейчас над ними баловаться... Smile

-------------

Урезал файл mainmenu.cam до 36 байт. Работает нормально! :blink:
Скорее всего Нивальцы опять что-то хотели, но недоделали...
Узнал, что первые два поля (из девяти в одном блоке) камеру не трогают, остальные её крутят как-то непонятно... может быть, даже по кругу. :ph34r:

-------------

Итак, нулевое и первое поля ещё не известны.
Поле 2: Смещение на восток;
Поле 3: Смещение на север;
Поле 4: Смещение в небо.
Всё-таки в этих полях перемещение идёт по прямой. Smile

--------------

Поля 5,6,7,8 поворачивают камеру. Но вот делают они это очень не хорошо! :angry:
Очень странная тректория поворота камеры.

Но всё-таки смог немного разобраться:
Поля 7 и 8 делаю поворот в одну сторону (при увеличении камера поворачивается к небу, если смотрела прямо). Если записать в поле 7 ноль, то камера будет смотреть в небо, а если записать в поле 8 ноль, а в поле 7 число (0>xxx>1), то камера будет смотреть на землю. Чтобы камера смотрела прямо, желательно в поле 7 поставить -1, а в поле 8 поставить 1 (скорее всего камера становится в разницу между этими значениями).
Поля 5 и 6 ещё кривее предыдущих. Они тоже работают на пару. Если увеличивать эти поля, причём сохранять их равными, то камера будет проворачиваться набок против часовой стрелки. А вот если значения этих полей увеличивать, но при этом сохранять их равными с противоположными знаками, то камера будет поворачиваться, как обычные юниты поворачиваются, только при увеличении значений резко падает чуствительность камеры и её начинает косить (это дело выравнивается подборкой мелкой разницы между абсолютными значениями полей).

Хух, я бы лучше понял логику поворота камеры, скорее всего, если бы знал, как обычно в играх реализую работу с камерой. А так вот приходится вертеться. Sad

Смысл первых двух полей я так и не понял. Знаю, что второе поле часто бывает отключено (FF FF FF FF), а в первом гигантское значения записаны, но в разумных пределах для float - скорее всего это ID, или что-то типа номерка... :unsure:

Пока на этом работы с форматом CAM останавливаю. Мне удобнее всего их было менять спомощью ArtMoney 7.08 - она файлы править умеет, причём позволяет разбивать файл на поля нужно типа. Wink
Ответ
#2
Цитата:Хух, я бы лучше понял логику поворота камеры, скорее всего, если бы знал, как обычно в играх реализую работу с камерой. А так вот приходится вертеться

Ключевое слово здесь - кватернионы.В формате cam все сделано четко и логично.Не следует оправдывать собственное незнание кривосью Нивала.

Возьми самый большой файл cam (не помню уже его название).
На нем удобно проводить изучение.

4 байта - время камеры (если записей положения больше чем 1)
4 байта - хз...не помню что за поле
3 блока по 4 байта - координаты x,y,z
4 блока по 4 байта - кватернион поворота камеры

итого 9 блоков по 4 байта и есть наши 36 байт на одну запись положения.
Ответ
#3
Теперь у меня в плане работ будет ещё и изучение кватернионов (которые, как я понял, относятся к фракталам и комплексным числам, о которых я ничего не знаю).

p.s.: про Нивал вообще-то я ничего не говорил.
Ответ
#4
ГЫ ) Во-первых, фрактал и комплексные числа - две большие разницы. Во-вторых, кватернион к ним тоже никакого отношения не имеет.

З.Ы. Кватернион в данном случае просто набор четырех координат (XYZW).
Duty is everything, the greatest of joys, the deepest of sorrows.
Ответ
#5
ALtair, прости, просто я грубо написал, я имел ввиду, что кватернионы относятся к фракталам и комплексным числам по сложности, т.к. всё это высшая математика.
Вообще кватернион в данном случае уж точно не координаты описывает (это я сам на собственной шкуре проверял), а именно поворот камеры он описывает.
Ответ
#6
В трехмерной геометрии поворот задается координатами вектора поворота, если не ошибаюсь. А вообще в 3Д Графике по идее поворот должен задаваться матрицей.
Duty is everything, the greatest of joys, the deepest of sorrows.
Ответ
#7
ALtair, сможешь меня неумного научить эти кватернионы переводить в обычные градусы? Sad Huh
Ответ
#8
эээ. Если б я сам умел Smile Тебе поможет MSDN, раздел DirectX9.
Duty is everything, the greatest of joys, the deepest of sorrows.
Ответ
#9
yandex, google, Google groups :blink:
Ответ
#10
Ладно, просто скажу, что хотел вообще придумать алгоритм, который, имея расположение камеры (x,y,z) и точку, куда она должна смотреть, соответственно её повернёт. :unsure:

---------------------

Вот, есть две ссылки неплохие по поводу кватернионов:
http://algolist.manual.ru/graphics/3dfaq...les/77.php
http://itsoyuz.h10.ru/articles/d3d/quat.html
Так вот, там всё довольно подробно объяснено.
Нет не у кого желания попробовать реализовать задумку с камерой (по двум точкам)?

Я вот уже научился немного делать эти кватернионы. Теперь у меня другая проблема, попробую объяснить её суть:

Итак, мы имеет две 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%????

Может я вообще не в ту степь лезу? Sad Просто очень хочется с делом этим разобраться. Sad
Ответ
#11
ALtair, а сможешь рассчитать матрицу3x3 поворота по начальной и конечной точке? Просто я нашёл алгоритм, который переводит матрицу в кватернион, но вот теперь задать матрицу проблема. Как ни пытаюсь не пойму. Там в матрице целых три вектора задавать надо, а я могу только один получить по начальной и конечной точкам. Как остальные два вектора найти? Huh Sad
Ответ
#12
Опять же, пишу по памяти, вполне возможно, что не прав. При простых преобразованиях (поворот, смещение и т.д.), задаваемых матрицами, в самой матрице используется только 4 ячейки. Конфигурация используемых ячеек и функции, подставляемые в ячейки, тебе придется поискать в инете.
Duty is everything, the greatest of joys, the deepest of sorrows.
Ответ
#13
Вижу что это давно обсуждалось Smile сам занят разработкой cam едитора , но у меня возникли нсколько проблем ( я пишу на Blitz3D ибо на нем 3д делать просто , следственно у меня 3д cam едитор Smile ) вообщем при чтении самого большего файла с камерами получается деформированный овал из камер ( я так предполагаю это границы камеры на базе ) но они расположены перпендикулярно плоскости , меня это почемуто настораживает . возможно в кам файле координаты хранятся не в прямом порядке ? Ну и насчет кватернионов , опятьже непонятно как они хранятся XYZW или WXYZ или еще как нибудь Smile .

Кому интересно вот библа , для 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#

    sint = (2 * srcw * srcy) - (2 * srcx * srcz)
    cost_temp = 1.0 - (sint * sint)

    If Abs(cost_temp) > QuatToEulerAccuracy
 cost = Sqr(cost_temp)
    Else
 cost = 0
    EndIf

    If Abs(cost) > QuatToEulerAccuracy
 sinv = ((2 * srcy * srcz) + (2 * srcw * srcx)) / cost
 cosv = (1 - (2 * srcx * srcx) - (2 * srcy * srcy)) / cost
 sinf = ((2 * srcx * srcy) + (2 * srcw * srcz)) / cost
 cosf = (1 - (2 * srcy * srcy) - (2 * srcz * srcz)) / cost
    Else
 sinv = (2 * srcw * srcx) - (2 * srcy * srcz)
 cosv = 1 - (2 * srcx * srcx) - (2 * srcz * srcz)
 sinf = 0
 cosf = 1
    EndIf

; 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#

    cosom = startx * finx + starty * finy + startz * finz + startw * finw

    If cosom <= 0.0
 cosom = -cosom
 scaler_w = -finw
 scaler_x = -finx
 scaler_y = -finy
 scaler_z = -finz
    Else
 scaler_w = finw
 scaler_x = finx
 scaler_y = finy
 scaler_z = finz
    EndIf

    If (1 - cosom) > QuatSlerpAccuracy
 omega = ACos(cosom)
 sinom = Sin(omega)
 scale0 = Sin((1 - t) * omega) / sinom
 scale1 = Sin(t * omega) / sinom
    Else
; Angle too small: use linear interpolation instead
 scale0 = 1 - t
 scale1 = t
    EndIf

    resx = scale0 * startx + scale1 * scaler_x
    resy = scale0 * starty + scale1 * scaler_y
    resz = scale0 * startz + scale1 * scaler_z
    resw = scale0 * startw + scale1 * scaler_w
End Function

; 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 Думаю понять его будет нетрудно так как это проктически обычный бейзик .

Забыл в предыдущем посте написать ник Smile вообщем если сможете чем помочь или может я смогу вам чем помочь Smile вот мои контакты
ICQ 272529694
mail conan_fedr_666@mail.ru
MSN conan_fedr_666@mail.ru

Вообщем вотЪ мне нужна помощь , мой кам вьюер очень глючный , несчитая того что я возможно неправельно пересчитываю координаты , он еще почемуто все камы кроме самого большего несовсем правельно отображает в плане того что видна лиш одна камер , я незнаю изза чего это хотя сбоку в меню отображаются что камер 9 или больше в зависимости от файла , очень странное явление .

Вообщем вот мой исходник , тут используются либы quaternions опубликованная выше и XUI2 либа интерфейса . Прошу вас посмотреть и порекомендовать все что можно от координат и угла до того как правельнее организовать интерфейс и глючащих камер Smile . Также я прилагаю архив в котором скомпилиная прога со всем необходимым , извините правда она неудобная очень я ее очень мало писал буквально пару часов . Чтобы подгрузить в нее какойнить файл нада в блокнотике который идет с ней написать имя этого файла с расширением ессесно cam Smile , положить этот файл в папку с прогой и запустить программу Smile , да еще необходим DirectX не меньше 7 версии . Вот все вообщем Smile

Исходник :
Код:
; Включения
Include "XUI2.bb"
Include "Quaternions.bb"

; Константы
Const APP_TITLE$ = "-$[CAMedit by Conan Fedr]$-  ЛВ Delovepers Group"

; Глобальные переменные
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)

; Инициализация интерфейса
XUI2_Init("XUI2_SKINSXUI2_WINXP_LUNA_S.xuiskin",True,False,True,"ENG")
XUI2_InitWindowSnap(True,5)

; Построение шаблона сцены
SceneGrid = LoadMesh("grid.b3d")

Global CameraMarker = LoadMesh("cam_marker.3ds")
ScaleEntity CameraMarker,0.3,0.3,0.3
HideEntity(CameraMarker)

Global Camera = CreateCamera()
PositionEntity Camera,0,5,0
CameraClsColor Camera,50,150,255

Light = CreateLight()

; Вызовы пользовательских функций
CreateInterface()

hzname = OpenFile("filename.txt")
ReadCam(ReadLine(hzname))
CloseFile(hzname)

; Основной цикл
Repeat
    Cls

    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_label_name = XUI2_Label(tool_window,87,10,"Tools",4,1)
    
    tool_group_zap = XUI2_GroupBox(tool_window,10,30,180,200,".cam Nodes",0,0)
    tool_list_nodes = XUI2_ListView(tool_group_zap,10,10,90,170,"Bla!",4,"LIST",1,1,"hz")
;tool_button_nodes_select = XUI2_Button(tool_group_zap,10,160,75,20,"Select","hz")
;tool_button_nodes_select = XUI2_Button(tool_group_zap,95,160,75,20,"Cansel","hz")
    
    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()

 CamNodeCamMarker = CopyEntity(CameraMarker)
 PositionEntity CamNodeCamMarker,CamNodePosX,CamNodePosY,CamNodePosZ
 QuatToEuler(CamNodeRot,Quatr)
 RotateEntity CamNodeCamMarker,CamNodeRotPitch,CamNodeRotyaw,CamNodeRotroll
 EntityPickMode CamNodeCamMarker,2

 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

Блиин у вас низя гостям циплять файлы , ну лана закачаю на фтп ...
Вот сцылко на архив с прогой : http://www.cool.hut1.ru/XUI2_Demo_Release_05-08-20.rar

PS Очень нужна помощь Smile

Опять забыл Smile написать кнопки для управления :
W - поворот камеры вверх
S - поворот камеры вниз
Up - Передвежение камеры вперед
Down - Передвежение камеры назад
Left - поворот камеры в лево
Right - поворот камеры в право
Alt + Left Mouse Button - Произвольное вращение камеры
Ответ
#14
2ELF
"Quaternion {x, y, z, w}" - не верно! Всё работает на WXYZ-настройках. Проблемма редактора камов полностью решена вчера - 18 фефраля 2006 года, да будет памятен этот день %) И спасибо некоторым личностям, которые сильно помогли это сделать.

PS: Из скрина видно, что камера настроена как надо Smile


Файлы вложений Эскизы(ов)
   
Ответ
#15
Снайп Smile это камедитор вопервых ГГшный , вовторых он работает под ГГшным мини редактором . В третьих я хочу забахать свой редактор Smile что у всех был редатор ане только у вас Smile .

PS КалбасКа злой редиска Smile
Ответ
#16
2MerkuiY
Снайп невиноват что он неможет дать редактор все , хотя незнаю хочит он этого или нет Blush . В этом виноват :
КалбасКа злой редиска Smile (С) Conan Fedr
Ответ
#17
Руки есть?
Комп в порядке?
Формат кама известен?
Формулы рабочие есть?
Кватерион считать умеем?
С 3-д программингом знаком?
Буфер данных обрабатывать умеешь?
--------------------------------------------------?
Так что орать на Калбаса, если ты и сам можешь?
А если не можешь сам - так что винить в этом других?
Ответ
#18
Как говорится...

"Если ты ни на что не способен! - Ты ничего не должен хотеть"
Ответ
#19
"Но тебе то пох должно быть =)"
По себе людей не судят. Я вот написал там маленький списочек вопросов. Вот пусть тот, кто намеревается сделать эдитор ответит отрицательно хоть на 1 вопрос до разделителя - тогда и будем разбираться. А пока - вперёд и с песней
Ответ
#20
Я непонял чо тут все на меня наезжают ? Smile
У меня тоже есть camEditor уже рабочий Smile только недоделаный еще .
Ну раз вы меня так благадарите у меня вся охота работать отпадает ...

2Jack
Мне интересно кому ты это сказал ?

PS Вообщето когда на когото наезжают на форуме принято писать 2ник_пациента
Ответ


Перейти к форуму:


Пользователи, просматривающие эту тему: 4 Гость(ей)