PDA

Просмотр полной версии : 0x00A9 SMSG_UPDATE_OBJECT (GAMEOBJECT_PARENTROTATION)


Konctantin
19.07.2010, 22:11
Пакет А9, в нем содержится данные о координатах в часности и ГО, все бы так и ничего, но вот до 3.1.0 поля GAMEOBJECT_PARENTROTATION[4] содержали содержали информацию об наклонах ГО вокруг своей оси.

А с обновлением 3.1.0 было добавлено еще одно поле (uint64)rotation, которое содержится в мовемент блоке, и сейчас, на сколько я понимаю, ротация упакована как раз в в это поле.

В мангосе есть функция, которая упаковывает значения с БД в это поле:

void GameObject::UpdateRotationFields(float rotation2 /*=0.0f*/, float rotation3 /*=0.0f*/)
{
static double const atan_pow = atan(pow(2.0f, -20.0f));

double f_rot1 = sin(GetOrientation() / 2.0f);
double f_rot2 = cos(GetOrientation() / 2.0f);

int64 i_rot1 = int64(f_rot1 / atan_pow *(f_rot2 >= 0 ? 1.0f : -1.0f));
int64 rotation = (i_rot1 << 43 >> 43) & 0x00000000001FFFFF;

//float f_rot2 = sin(0.0f / 2.0f);
//int64 i_rot2 = f_rot2 / atan(pow(2.0f, -20.0f));
//rotation |= (((i_rot2 << 22) >> 32) >> 11) & 0x000003FFFFE00000;

//float f_rot3 = sin(0.0f / 2.0f);
//int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f));
//rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000;

m_rotation = rotation;

if(rotation2==0.0f && rotation3==0.0f)
{
rotation2 = (float)f_rot1;
rotation3 = (float)f_rot2;
}

SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2);
SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3);
}


Но исходя из этой функции, реально задействованы только 2 поля из 4 (rotation2 и rotation3), а как же быть с rotation0 и rotation1 если в самом этом поле, (uint64)rotation содержится 3 значения.

в клиенте нашел вот такое:
int __thiscall CGObject_C__TranslateRotation(void *this, int a2)
{
int v3; // edx@1
void (*v4)(void); // eax@1
int v5; // [sp+Ch] [bp-Ch]@1
float v6; // [sp+10h] [bp-8h]@1
float v7; // [sp+14h] [bp-4h]@1

v3 = *(_DWORD *)this;
*(float *)a2 = 0.0;
*(float *)(a2 + 4) = 0.0;
v4 = *(void (**)(void))(v3 + 52);
*(float *)(a2 + 8) = 0.0;
*(float *)(a2 + 12) = 1.0;
v7 = 1.0;
*(float *)&v5 = 0.0;
v6 = 0.0;
v4();
sub_982400(0.0, (int)&v5);
return a2;
}

int __thiscall sub_982400(int this, float a2, int a3)
{
int result; // eax@1
float v4; // ST08_4@1
double v5; // st7@1
float v6; // [sp+Ch] [bp-4h]@1

v4 = a2 * 0.5;
a2 = cos(v4);
v6 = sin(v4);
result = a3;
*(float *)(this + 12) = a2;
v5 = v6;
*(float *)this = *(float *)result * v6;
*(float *)(this + 4) = *(float *)(result + 4) * v5;
*(float *)(this + 8) = v5 * *(float *)(result + 8);
return result;
}
Думал, немного прояснит ситуацию, ан нет, все так и осталось загадкой.

Пробовал написать обратную функцию, чтоб получить из (uint64)rotation и orientation получить 2 поля (float)rotation2 и (float)rotation3 но получил совсем не то, что надо.

Объясните пожалуйста, как это должно работать? или подскажите куда копать.
И вообще, содержатся ли в апдейтполях GAMEOBJECT_PARENTROTATION[4] хоть какая-то полезная информация? или они остались как осколки прошлого?

Deamon
19.07.2010, 22:26
Вот так выглядели апдейт поля до 3.1.0

GAMEOBJECT_DISPLAYID = 8; // 001 - [1] Integer - [001] PUBLIC
GAMEOBJECT_FLAGS = 9; // 001 - [2] TwoWords - [001] PUBLIC
GAMEOBJECT_ROTATION = 10; // 002 - [4] uInt64 - [001] PUBLIC
GAMEOBJECT_PARENTROTATION = 12; // 004 - [3] Single - [001] PUBLIC
GAMEOBJECT_POS_X = 16; // 001 - [3] Single - [001] PUBLIC
GAMEOBJECT_POS_Y = 17; // 001 - [3] Single - [001] PUBLIC
GAMEOBJECT_POS_Z = 18; // 001 - [3] Single - [001] PUBLIC
GAMEOBJECT_FACING = 19; // 001 - [3] Single - [001] PUBLIC
GAMEOBJECT_DYNAMIC = 20; // 001 - [2] TwoWords - [256] DYNAMIC
GAMEOBJECT_FACTION = 21; // 001 - [1] Integer - [001] PUBLIC
GAMEOBJECT_LEVEL = 22; // 001 - [1] Integer - [001] PUBLIC
GAMEOBJECT_BYTES_1 = 23; // 001 - [5] FourBytes - [001] PUBLIC
GAMEOBJECT_END = 24;

В 3.1.0 поле GAMEOBJECT_ROTATION просто перекочевало в мувмент блок. Не более.

А вот для чего нужны GAMEOBJECT_PARENTROTATION лично для меня остается загадкой.

Konctantin
19.07.2010, 23:29
но все же, как правильно получить поля rotation0, rotation1, rotation2, rotation3 для таблицы gameobject?

GriffonHeart
20.07.2010, 04:14
но все же, как правильно получить поля rotation0, rotation1, rotation2, rotation3 для таблицы gameobject?
Значения в SMSG_UPDATE_OBJECT приходят.

enum EGameObjectFields
{
...
GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC
...
}

Здесь все 4 значения, которые тебе нужны.

Когда-то делал для трупожорки:
obj0361:
f01_update_type: UPDATETYPE_CREATE_OBJECT (0x2)
f02_guid: 0xF11002FB970009B0
f03_type_id: TYPEID_GAMEOBJECT (0x5)
f04_movement_updateblock:
f010_rotation: 1355697
f01_flags1: UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION | UPDATEFLAG_ROTATION (0x350)
f03_3_1_x: 563.069
f03_3_2_y: 70.785
f03_3_3_z: 395.695
f03_3_4_o: -1.571
f05_4_pos_x: 563.069
f05_4_pos_y: 70.785
f05_4_pos_z: 395.695
f05_GUID_HIPART: 0x970009b0L
f05_p_orient: 0.000
unk_q: 0

f05_values_updateblock:
0000: ('OBJECT_GUID_LOW', 2533362096L)
0001: ('OBJECT_GUID_HIGH', 4044358395L)
0002: ('OBJECT_TYPE', 33)
0003: ('OBJECT_ENTRY', 195479)
0004: ('OBJECT_SCALE_X', 2.1942160129547119)
0008: ('GAMEOBJECT_DISPLAYID', 9041)
0012: ('GAMEOBJECT_PARENTROTATION3', 0.70710670948028564)
0013: ('GAMEOBJECT_PARENTROTATION4', 0.7071068286895752)
0014: ('GAMEOBJECT_DYNAMIC', 4294901762L)
0017: ('GAMEOBJECT_BYTES_1', 4278198017L)
Здесь:
orientation = f03_3_4_o
rotation0 = 0
rotation1 = 0
rotation2 = GAMEOBJECT_PARENTROTATION3
rotation3 = GAMEOBJECT_PARENTROTATION4
-----------------------------------
Если конечно ничего не изменилось....

Konctantin
20.07.2010, 09:15
rotation2 = GAMEOBJECT_PARENTROTATION3
rotation3 = GAMEOBJECT_PARENTROTATION4

Я тоже так делал, но получается бяка... в одном пакете пришли координаты ГО и ротация у них у всех ОДИНАКОВАЯ, и когда я залил их в базу, то получил что попало, таблички стали косо, и стояли прямо, место того, чтоб "прилечь" на подножье статуи.

Вот по этому, и спрашиваю.

TOM_RUS
20.07.2010, 10:33
А Вы уверены что все корректно залилось в базу? Кроме вас пока на это никто не жаловался...

Konctantin
20.07.2010, 14:00
Вот скрины с оффа:
http://xmages.net/storage/10/1/0/e/3/thumb/thumb_cbf14d62.jpg (http://xmages.net/show.php/1618666_wowscrnshot-072010-131223-jpg.html) http://xmages.net/storage/10/1/0/e/3/thumb/thumb_3955876b.jpg (http://xmages.net/show.php/1618665_wowscrnshot-072010-131230-jpg.html) http://xmages.net/storage/10/1/0/e/3/thumb/thumb_10bcc3b2.jpg (http://xmages.net/show.php/1618664_wowscrnshot-072010-131317-jpg.html)
http://xmages.net/storage/10/1/0/e/3/thumb/thumb_58404e33.jpg (http://xmages.net/show.php/1618663_wowscrnshot-072010-131302-jpg.html) http://xmages.net/storage/10/1/0/e/3/thumb/thumb_cd6796b1.jpg (http://xmages.net/show.php/1618662_wowscrnshot-072010-131225-jpg.html) http://xmages.net/storage/10/1/0/e/3/thumb/thumb_2c2fdffa.jpg (http://xmages.net/show.php/1618661_wowscrnshot-072010-131311-jpg.html)
http://xmages.net/storage/10/1/0/e/3/thumb/thumb_614dc7a7.jpg (http://xmages.net/show.php/1618668_wowscrnshot-072010-131216-jpg.html) http://xmages.net/storage/10/1/0/e/3/thumb/thumb_8f9c4996.jpg (http://xmages.net/show.php/1618667_wowscrnshot-072010-131241-jpg.html)
вот полученный обработанный дамп:
/*
175679 214 9 The Skull of Tyrannistrasz
175680 214 9 Fossilized Egg
175681 214 9 Roc Talon
175682 214 9 Geru Strider
175683 214 9 Toothgnashers Skeleton
175686 214 9 Highborne Astrolabe
175688 214 9 Horde Catapult
175689 214 9 Uldaman Reliefs
*/

REPLACE INTO `gameobject` VALUES
(1073744492, 175680, 0, 1, 1, -4698.274000, -1312.965000, 503.944300, 1.039072, 0.000000, 0.000000, 0.904455, 0.426569, 300, 100, 1),
(1056967311, 175679, 0, 1, 1, -4714.706000, -1325.925000, 504.599000, -0.165149, 0.000000, 0.000000, 0.904455, 0.426569, 300, 100, 1),
(1107298993, 175682, 0, 1, 1, -4682.517000, -1322.510000, 506.095500, 2.076940, 0.000000, 0.000000, 0.904455, 0.426569, 300, 100, 1),
(1124076359, 175683, 0, 1, 1, -4680.762000, -1301.001000, 504.092300, 0.882651, 0.000000, 0.000000, 0.904455, 0.426569, 300, 100, 1),
(1090521958, 175681, 0, 1, 1, -4695.435000, -1318.034000, 504.075000, 1.039072, 0.000000, 0.000000, 0.904455, 0.426569, 300, 100, 1),
(1174407634, 175686, 0, 1, 1, -4625.645000, -1262.276000, 503.649600, -2.993235, 0.000000, 0.000000, 0.904455, 0.426569, 300, 100, 1),
(1191184851, 175687, 0, 1, 1, -4594.844000, -1257.882000, 506.557700, 2.461345, 0.000000, 0.000000, 0.904455, 0.426569, 300, 100, 1),
(1207962108, 175688, 0, 1, 1, -4602.465000, -1234.719000, 504.472100, 0.000000, 0.000000, 0.000000, 0.904455, 0.426569, 300, 100, 1),
(1224739375, 175689, 0, 1, 1, -4585.965000, -1223.390000, 504.293300, 1.192050, 0.000000, 0.000000, 0.904455, 0.426569, 300, 100, 1);


в аттаче сам снифф, формат PKT:

в базу заливал, значения такие-же.
Выложить скрины с сервака не могу, так как его у меня нету, сейчас соберу и "сфоткаю результат", но и без скринов понятно, что что-то не правильно, так как у всех одинаковая ротация:
OBJECT_FIELD_ENTRY 175680
GAMEOBJECT_PARENTROTATION_2 0.904455
GAMEOBJECT_PARENTROTATION_3 0.426569

OBJECT_FIELD_ENTRY 175679
GAMEOBJECT_PARENTROTATION_2 0.904455
GAMEOBJECT_PARENTROTATION_3 0.426569

OBJECT_FIELD_ENTRY 175682
GAMEOBJECT_PARENTROTATION_2 0.904455
GAMEOBJECT_PARENTROTATION_3 0.426569

OBJECT_FIELD_ENTRY 175683
GAMEOBJECT_PARENTROTATION_2 0.904455
GAMEOBJECT_PARENTROTATION_3 0.426569

OBJECT_FIELD_ENTRY 175686
GAMEOBJECT_PARENTROTATION_2 0.904455
GAMEOBJECT_PARENTROTATION_3 0.426569

OBJECT_FIELD_ENTRY 175687
GAMEOBJECT_PARENTROTATION_2 0.904455
GAMEOBJECT_PARENTROTATION_3 0.426569

OBJECT_FIELD_ENTRY 175688
GAMEOBJECT_PARENTROTATION_2 0.904455
GAMEOBJECT_PARENTROTATION_3 0.426569

OBJECT_FIELD_ENTRY 175689
GAMEOBJECT_PARENTROTATION_2 0.904455
GAMEOBJECT_PARENTROTATION_3 0.426569

LordJZ
20.07.2010, 14:04
...
формат PKT:
...Konctantin имеет ввиду WowCore формат, открываемый вьювером от TOM_RUS

Konctantin
20.07.2010, 14:36
Вот скрин с сервера:
http://dl.dropbox.com/u/9241118/WoWScrnShot_072010_153059.jpg

RomanRom2
20.07.2010, 16:28
я чот смотрю смотрю и не пойму проблемы.
если взять снифф, влить в базу респонс ГО, влить в мир А9 со снифа, один в один. то какая проблема тогда может возникнуть то? чудес не бывает, значит где то ошибаетесь в парсинге. не те поля не в свои места складываете в базе.

размышляю: однозначно можно сказать, что респонс на ГО ни как не должен влиять на расположение ГО в мире - ГО может быть несколько одинаковых, но стоять по разному.

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

Konctantin имеет ввиду WowCore формат, открываемый вьювером от TOM_RUS
я все же надеюсь, что когда нибудь PKT формат станет централизованным стандартом :)

добавлено.
парсинг снифа:
--- NEW OBJECT [015/063]---------------------------------------------------------------
update type = UPDATE_TYPE_CREATE_FULL, ofs=0843
GUID F11002AE40000A6C
unit type = (5) GAME_OBJECT, ofs=0844

20.07.2010, 17:35:07:
create flags: 0x0350
flag0 (0x100): guid_unk1 = 0000000000000000
flag0 (0x100): x1=-4698.273926, y1=-1312.965088, z1=503.944275
flag0 (0x100): x2=-4698.273926, y2=-1312.965088, z2=503.944275
flag0 (0x100): f1=1.039072, f2=0.000000
flag0 (0x10) = 40000A6C
flag0 (0x200): guid_unk2 = 00000000E489B91B
BitMask blocks = 1

20.07.2010, 17:35:07: A9: added ParseGameobject
20.07.2010, 17:35:07:
0 OBJECT_FIELD_GUID_LO 40000A6C (1073744492)
1 OBJECT_FIELD_GUID_HI F11002AE (-250608978)
2 OBJECT_FIELD_TYPE 00000021 (33)
3 OBJECT_FIELD_ENTRY 0002AE40 (175680)
4 OBJECT_FIELD_SCALE_X 3FCCCCCD (1.600000)
8 GAMEOBJECT_DISPLAYID 000000D6 (214)
12 GAMEOBJECT_PARENTROTATION_3 3F678A60 (0.904455)
13 GAMEOBJECT_PARENTROTATION_4 3EDA6737 (0.426569)
14 GAMEOBJECT_DYNAMIC FFFF0000 (-65536)
17 GAMEOBJECT_BYTES_1 FF000901 (-16774911)
--- NEW OBJECT [016/063]---------------------------------------------------------------
update type = UPDATE_TYPE_CREATE_FULL, ofs=08A9
GUID F11002AE3F000A8F
unit type = (5) GAME_OBJECT, ofs=08AA

20.07.2010, 17:35:07:
create flags: 0x0350
flag0 (0x100): guid_unk1 = 0000000000000000
flag0 (0x100): x1=-4714.706055, y1=-1325.925049, z1=504.599030
flag0 (0x100): x2=-4714.706055, y2=-1325.925049, z2=504.599030
flag0 (0x100): f1=-0.165149, f2=0.000000
flag0 (0x10) = 3F000A8F
flag0 (0x200): guid_unk2 = 00000000DF825A2D
BitMask blocks = 1

20.07.2010, 17:35:07: A9: added ParseGameobject
20.07.2010, 17:35:07:
0 OBJECT_FIELD_GUID_LO 3F000A8F (1056967311)
1 OBJECT_FIELD_GUID_HI F11002AE (-250608978)
2 OBJECT_FIELD_TYPE 00000021 (33)
3 OBJECT_FIELD_ENTRY 0002AE3F (175679)
4 OBJECT_FIELD_SCALE_X 3FCCCCCD (1.600000)
8 GAMEOBJECT_DISPLAYID 000000D6 (214)
12 GAMEOBJECT_PARENTROTATION_3 3F678A60 (0.904455)
13 GAMEOBJECT_PARENTROTATION_4 3EDA6737 (0.426569)
14 GAMEOBJECT_DYNAMIC FFFF0000 (-65536)
17 GAMEOBJECT_BYTES_1 FF000901 (-16774911)

в вашем случае разные параметры, которые я тут обзываю flag0 (0x100): f1 и f2. вы их задаете в A9 на своем сервере? подозреваю, это то что вам нужно.

З.Ы. кстати, снифф имеет неправильный заголовок.
первые три байта понятно - PKT
четвертый и пятый байты - версия сниффа. у вас 2.2, значит тут должно быть 0х0202
далее SnifferID - 0х06.

у вас же вот так: P,K,T,0x06,0x00,0x00.
должно быть P,K,T,0x02,0x02,0x06.

Konctantin
20.07.2010, 16:40
Ну как видите, координаты нормальные, а вот сама ротация косячит.
Ротация это как раз эти самые 4 апдейт поля: GAMEOBJECT_PARENTROTATION[4], но ведь остальные поля парсятся нормально, нифига понять не могу.

Konctantin
20.07.2010, 17:11
2. PKT-файлы
-------------------------
заголовок файла для декодированных данных:
- 3 байта: [P], [K], [T]
- 2 байта: версия снифа. в настоящий момент версия 2.1. в старшем байте хранится 1, в младшем 2
- 2 байта: билд клиента
- 40 байт: ключ, все нули
- ?? байт: данные

Я чего-то не пойму, а
.Ы. кстати, снифф имеет неправильный заголовок.
первые три байта понятно - PKT
четвертый и пятый байты - версия сниффа. у вас 2.2, значит тут должно быть 0х0202
далее SnifferID - 0х06.
в описании у вас не хватает SnifferID - 0х06?


Вот так пойдет?

private void OpenFileAndWriter()
{
CurrentFile = new WPLFileInfo(String.Format(@"{0}/{1:yyyy-MM-dd_HH-mm-ss-ffff}.pkt", LogsFolder, DateTime.Now), DateTime.Now);
Writer = new BinaryWriter(new FileStream(CurrentFile.FileName, FileMode.Create));
Writer.Write('P');
Writer.Write('K');
Writer.Write('T');
Writer.Write((byte)0x02);
Writer.Write((byte)0x02);
Writer.Write((byte)0x06);
Writer.Write((ushort)12340);// build (todo: read from config)
Writer.Write((uint)0); // locale
Writer.Write(new byte[20]); // sessionKey
Writer.Write(new byte[64]); // realmName
}

RomanRom2
20.07.2010, 17:35
Я чего-то не пойму, в описании у вас не хватает SnifferID - 0х06? Вот так пойдет?

так, давайте поставим точку в этом вопросе раз и навсегда.

на сайте опубликована версия 2.1 сниффа.
но существует еще и версия 2.2, она отличается от 2.1 только заголовком самого сниффа, а именно:

P,K,T, - вид сниффа, PKT или RAW.
0х02, 0х02 - версия сниффа

эти пять байт всегда означают эти поля - вид и версия. дальнейший заголовок зависит от версии сниффа.
- для 2.1
2 bytes: client build
40 bytes: session key

- для 2.2
1 byte: sniffer ID
2 bytes: client build
4 bytes: language
20 bytes: session key (obsolete)
64 bytes: realm name

по поводу вашего сниффа:
ваш содержит в заголовке следующие данные:
0000000000: 50 4B 54 06 00 00 34 30 │ 00 00 00 00 00 00 00 00
50 4B 54 - PKT
далее должно быть 0х02, 0х02 - версия сниффа, а у вас 0х06.
далее у вас два нуля,
далее билд клиента

ну видно что формат 2.2 используется, мои вьюверы просто не приняли снифф изза неправильной версии сниффа. поэтому я и сказал вам о неправильных данных в заголовке. у вас получилось 0х0600 вместо 0х0202 или 0х0102 ожидаемых.

я не знаю, почему получил распространение формат 2.2 у "сторонних" разработчиков, назовем их так, у нас он как то не прижился. мы сами используем версию заголовка 2.1.

как я уже говорил ранее, 2.2 "родился" в тот короткий момент, когда близзы сделали ключ 20ти байтным. это продолжалось буквально какие то 2-3 билда. поэтому 2.2 не может использоваться для хранения session key. наверное поэтому мы его и не используем. но раз уж столько софта написано и сниффов наснифано, то приходится вот поддерживать.

теперь собсно по делу: вы так и не ответили на вопрос - вы создаете ГО в мире с флагами 0х100 и соответствующими флоатами или нет?

Konctantin
20.07.2010, 18:12
с форматом вроде уже все ок, поправил
вы создаете ГО в мире с флагами 0х100 и соответствующими флоатами или нет?
да, именно так
соответствующими флоатами
Из блока мовемент: X Y Z O
И из апдейт полей: (float)GAMEOBJECT_PARENTROTATION[4]

RomanRom2
20.07.2010, 18:24
что кладете вот сюда для разных объектов ГО?
flag0 (0x100): f1=1.039072, f2=0.000000

Deamon
20.07.2010, 18:34
что кладете вот сюда для разных объектов ГО?
flag0 (0x100): f1=1.039072, f2=0.000000

Фак мой мозг, это же Девид Блейн.

flag0 (0x100): x1=-4698.273926, y1=-1312.965088, z1=503.944275
flag0 (0x100): x2=-4698.273926, y2=-1312.965088, z2=503.944275

А я то думал, где может скрыватся растягивание размеров ГО. А оно вот оно родимое. Сцуко.

По теме: если декомпилированный код, приведенный в первом посте действительно относится к ParentRotation, то он как-то забавно применяется... Числа полученные от элементов ParentRotation поэлементно домнажаются к уже существующему вектору. Но HexRays криво распарсил ассемблированный код и что там на самом деле происходит сейчас сказать трудно.

Konctantin
23.07.2010, 21:34
давайте дальше продолжим.
данные для полей rotation0, rotation1, rotation2, rotation3 (таблицы gameobject) упакованы в (uint64)rotation в movement блоке пакета A9.

а в самих полях GAMEOBJECT_PARENTROTATION[4] содержится какая-то дополнительная информация:
Числа полученные от элементов ParentRotation поэлементно домнажаются к уже существующему вектору.

Но я не могу понять как именно упаковано, ведь если смотреть на код:

int64 i_rot1 = int64(f_rot1 / atan_pow *(f_rot2 >= 0 ? 1.0f : -1.0f));
int64 rotation = (i_rot1 << 43 >> 43) & 0x00000000001FFFFF;

//float f_rot2 = sin(0.0f / 2.0f);
//int64 i_rot2 = f_rot2 / atan(pow(2.0f, -20.0f));
//rotation |= (((i_rot2 << 22) >> 32) >> 11) & 0x000003FFFFE00000;

//float f_rot3 = sin(0.0f / 2.0f);
//int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f));
//rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000;

то упаковываются 3 значения (это если учитывать и закоментированый код)
а если смотреть сюда, и если я понял правильно, то все 4:

*(float *)(this + 12) = orientation;
v5 = v6;
*(float *)this = *(float *)result * v6;
*(float *)(this + 4) = *(float *)(result + 4) * v5;
*(float *)(this + 8) = v5 * *(float *)(result + 8);


Как же все должно быть, ибо все что писалось выше, работает там где ГО стоят без всякого поворота.

Fmut
24.07.2010, 23:12
а в чем проблема? у вас ГО криво стоят?

Konctantin
24.07.2010, 23:16
именно так, стоят криво...

Но все что я не пробовал не дало ни какого результата...

Объясните мне пожалуйста, что передается в поле (long)rotation не упакованные ли поля (float)rotation[4] для таблицы gameobject а то я уже совсем запутался...


ЗЫ. Криво стоят те, которые должны бвть наклонены или повернуты по y-z оси (не отностится к ориентации)


ЗЫЫ.. Если все говорят что нет проблем, и все правильно, то приведите пожалуйста "правильную" запись для ГО что находятся в этом посте (http://ru-mangos.ru/showpost.php?p=10993&postcount=7)

Konctantin
24.07.2010, 23:31
единственное в чем я уже точно уверен, так это то, что 0.904455, 0.426569, это как-бы соотношение сторон в данных табличках в 2d плоскости.

GriffonHeart
25.07.2010, 05:38
именно так, стоят криво...

Объясните мне пожалуйста, что передается в поле (long)rotation не упакованные ли поля (float)rotation[4] для таблицы gameobject а то я уже совсем запутался...

Если судить по функции мангоса GameObject::UpdateRotationFields, то этот (long)rotation (который в функции называется m_rotation) - вообще не зависит от GAMEOBJECT_PARENTROTATION, а расчитывается на основе ориентации GetOrientation(), которая спокойно, в неизменном виде существует в мувмент-блоке и напрямую может быть записана в базу.

Далее
GAMEOBJECT_PARENTROTATION+0 - напрямую берётся из базы
GAMEOBJECT_PARENTROTATION+1 - напрямую берётся из базы
GAMEOBJECT_PARENTROTATION+2 - если = 0, то перерасчитывается на основе ориентации GetOrientation()
GAMEOBJECT_PARENTROTATION+3 - если = 0, то перерасчитывается на основе ориентации GetOrientation()
--------------------
От сюда напрашивается вывод, что из снифа нам нужна только ориентация (не та которая лонг упакованная) из мувмент-блока и GAMEOBJECT_PARENTROTATION+0, GAMEOBJECT_PARENTROTATION+1 - из апдейт-блока, причём GAMEOBJECT_PARENTROTATION+2 и GAMEOBJECT_PARENTROTATION+3 брать со снифа и записывать в базу не обязательно, их можно оставить равными нулю, тогда их мангос сам расчитает на основе ориентации (не той которая long упакованная)

LordJZ
25.07.2010, 05:59
Уже пробовали, в самый первый раз (по крайней мере, со слов Konctantin) делать именно так — фиг вам, все-равно криво они показываются.

Fmut
25.07.2010, 12:43
дайте координаты по которым можно портанутся, гляну у себя криво ли ГО стоит.

Konctantin
25.07.2010, 12:49
такс, оки, давайте будем рассуждать логически и откинем то что есть в мангосе.
давайте еще раз взглянем на на этот пост (http://ru-mangos.ru/showpost.php?p=10993&postcount=7), посмотрим скрины, посмотрим, сам снифф, посмотрим полученные sql statements. или если не верите, залейте сами.

Как вы можете видеть, у все одинаковые значения:
GAMEOBJECT_PARENTROTATION_2 0.904455
GAMEOBJECT_PARENTROTATION_3 0.426569

и честное слове меня это поражает:
со снифа и записывать в базу не обязательно, их можно оставить равными нулю, тогда их мангос сам расчитает на основе ориентации

как наклон по оси Y, поворот по оси Z можно рассчитать исходя из ориентации по оси X?

Konctantin
25.07.2010, 12:50
дайте координаты по которым можно портанутся, гляну у себя криво ли ГО стоит.

в этом посте все есть (http://ru-mangos.ru/showpost.php?p=10993&postcount=7)

Konctantin
25.07.2010, 13:03
Вот еще:

//id name (ulong)rotation

// таблички которые "лежат" (наклон 90)
175681 Roc Talon 4DC8DB46E489B91B
175680 Fossilized Egg 4DC8DB46E489B91B

// наклон приблизительно на 30-40 градусов
175686 Highborne Astrolabe D77F2BF3F610DE59

// наклон приблизительно на 10-15 градусов
175682 Geru Strider 08A737EB9CADBE5A

// ГО стоит прямо
152095 Moonpetal Lily 00000000001007A4


в мангосе, да и не только, обрабатываются значение только 21 бит, а остальное нет.
int64 rotation = (i_rot1 << 43 >> 43) & 0x00000000001FFFFF;

TOM_RUS
25.07.2010, 15:20
int __thiscall sub_982340(UnkFloats *this, int *a2)
{
long double v2; // st5@1
long double v4; // st6@1 wtf is v4?
int result; // eax@2

this->float0 = 0.0;
this->float4 = 0.0;
this->float8 = 0.0;
this->floatC = 0.0;
this->float0 = (double)(signed int)(*(_QWORD *)a2 >> 42) * 0.000000476837158203125;
this->float4 = (double)((signed int)(*(_QWORD *)a2 << 22 >> 32) >> 11) * 0.00000095367431640625;
this->float8 = (double)(signed int)(*(_QWORD *)a2 << 43 >> 43) * v4; // * 0.00000095367431640625 ?
v2 = this->float8 * this->float8 + this->float0 * this->float0 + this->float4 * this->float4;
if ( fabs(v2 - 1.0) >= v4 ) // ???
{
result = (int)this;
this->floatC = sqrt(1.0 - v2);
}
else
{
result = (int)this;
this->floatC = 0.0;
}
return result;
}

Konctantin
25.07.2010, 15:44
спасибо, но читать его крайне трудно, и понять что там, до конца невозможно.
можно в 2х словах объяснить что и к чему?

TOM_RUS
25.07.2010, 17:51
спасибо, но читать его крайне трудно, и понять что там, до конца невозможно.
можно в 2х словах объяснить что и к чему?

Из uint64 поля, находящегося в мувмент блоке клиент получает 4 флоата посредством приведенного выше кода. Видимо это как-то связано с вашей проблемой.

Fmut
26.07.2010, 00:36
Видимо теперь этим числом задается поворот ГО в пространстве и больше не используются GAMEOBJECT_PARENTROTATION.
И кроме как держать его в базе я другого пути пока не вижу.

Скриншот не могу прикрепить, форум режет урлы (

Вот разбор одного из такого ГО:
UpdateType = UPDATETYPE_CREATE_OBJECT
objGuid = $F11002AE3F000A87
objType = TYPEID_GAMEOBJECT ($5)
obj_flag (word) = $0358 ($0008,$0010,$0040,$0100,$0200)
if (obj_flag and UPDATEFLAG_POSITION) > 0 then begin
GUID (pGUID) = $0000000000000000
posX=-4714,7060546875
posY=-1325,92492675781
posZ=504,599029541016
posX=-4714,7060546875
posY=-1325,92492675781
posZ=504,599029541016
posR=-0,165148675441742
posR=0
end;
if (obj_flag and UPDATEFLAG_LOWGUID) > 0 then begin
LowGUID (int) = $00002AAA
end;
if (obj_flag and UPDATEFLAG_HIGHGUID) > 0 then begin
HighGUID (int) = $00000100
end;
if (obj_flag and UPDATEFLAG_ROTATION) > 0 then begin
GameobjectRotation (int64) = 1355986587154012717
end;

IndexCount = 1
OBJECT_FIELD_GUID = $F11002AE3F000A87
OBJECT_FIELD_TYPE = 33
OBJECT_FIELD_ENTRY = 175679
OBJECT_FIELD_SCALE_X = 1,60000002384186
GAMEOBJECT_DISPLAYID = 214
GAMEOBJECT_PARENTROTATION_3 = 0,904455184936523
GAMEOBJECT_PARENTROTATION_4 = 0,426568686962128
GAMEOBJECT_DYNAMIC = $FFFF0000
GAMEOBJECT_BYTES_1 = $FF000901

Konctantin
26.07.2010, 01:00
Скриншот не могу прикрепить, форум режет урлы (
добавьте нижние пробелы, и все примет.
Видимо это как-то связано с вашей проблемой.
это не только моя проблема, это проблема всех ГО, которые стоят не прямо.



void UnpackRotation(ulong data, ref float[] rotation)
{
double v1 = 0.000000476837158203125;
double v2 = 0.000000953674316406250;

rotation[0] = (float)( (data >> 42) * v1);
rotation[1] = (float)(((data << 22 >> 32) >> 11) * v2);
rotation[2] = (float)( (data << 43 >> 43) * v2);

float temp = (float)(Math.Pow(rotation[2], 2) + Math.Pow(rotation[1], 2) + Math.Pow(rotation[0], 2));

if (Math.Abs(temp - 1.0f) >= v2)
rotation[3] = (float)(Math.Sqrt(1.0f - temp));
else
rotation[3] = 0.0f;
}



но ожидаемого результата так и не получилось, во первых, насколько я понял значение ротации должно быть в диапазоне -1 до 1, а тут немного не то.

я еще попробую помучить это все.

Fmut
26.07.2010, 01:09
Вот как у меня сейчас упаковывается поворот в горизонтали:
function GetGORotation(R: Single): Int64;
begin
if Cos(R / 2) >= 0 then
Result := $1FFFFF and (Round(Sin(R / 2) / ArcTan(Power(2, -20))))
else
Result := $1FFFFF and (Round(Sin(R / 2) / ArcTan(Power(2, -20)) * (-1)));
end;

Neverdie
03.08.2010, 02:30
ребят не мучайтесь
константин уже сам ответил сам же в первом посту
вырезка из клиента

v3 = *(_DWORD *)this;
*(float *)a2 = 0.0;
*(float *)(a2 + 4) = 0.0;
v4 = *(void (**)(void))(v3 + 52);
*(float *)(a2 + 8) = 0.0;
*(float *)(a2 + 12) = 1.0;
v7 = 1.0;
*(float *)&v5 = 0.0;
v6 = 0.0;
v4();


Vladimir/- (02:24:14 3/08/2010)
ну блин, весь ответ в первом посту

Vladimir/- (02:24:23 3/08/2010)
преобразование кватерниона в матрицу вращения

Vladimir/- (02:24:29 3/08/2010)
99.9% что оно

Vladimir/- человек который не дописал колиду в кобольде -)))) (падлец)
ниже прилагаеца статья

http://www.gamedev.ru/code/articles/?id=4215

SilverIce
25.05.2011, 19:04
С последними изменениями (https://github.com/mangos/mangos/commit/2bcbc0fbfe63fab389e4f4f875ac215852bff8b6) вновь стало возможно получать повороты гейм объектов из сниффов
Я надеюсь разработчики базы воспользуются ею, т.к. в базах уже ~11к го без поворотов..

Lordronn
25.05.2011, 19:10
Т.е теперь мы их берем не из GAMEOBJECT_PARENTROTATION 1 -4, а вытаскиваем из UPDATEFLAG_ROTATION?Или можно оттуда и оттуда брать?

SilverIce
25.05.2011, 19:12
только из UPDATEFLAG_ROTATION т.к.
но вот до 3.1.0 поля GAMEOBJECT_PARENTROTATION[4] содержали содержали информацию об наклонах ГО вокруг своей оси.
сейчас эти поля пустые, а в 4х они возможно удалены или будут удалены