March 28, 2024, 18:05
bigger smaller reset     1020px Wide width Full width Reset   * *

Gildor's Forums

  Homepage Facebook Read news on Twitter Youtube channel Github page
Welcome, Guest. Please login or register.
Did you miss your activation email?

« previous next »
Print
Author Topic: PS3 "Packed" FVectorIntervalFixed32GPU тип  (Read 5400 times)
elonir
Newbie
*
Posts: 26


View Profile
« on: May 13, 2015, 17:18 »

Здравствуйте!

Столкнулся с UE3 игрой для PS3 которая использует "packed"  разновидность вершин VertsHalfPacked

Очень понравились модели от-туда поэтому решил написать скрипт для импорта моделей, это PSN игра

На 3 координаты vx,vy,vz 32 бита, нужно их распаковать что бы получить корректные вершины Smiley

Согласно исходникам Umodel'a x - 11 бит, y - 11 бит, z - 10 бит (Спасибо огромное Гилдору, за всю его помощь  Smiley)

Вот, маленький пример "Packed" FVector (DWORD 32 бита) для первой вершины моей модели - 0x 78 35 93 7C ( в битах 01111000 00110101 10010011 01111100)

vx=01111000001 (961); vy=10101100100 (1380); vz=1101111100 (124)

Потом опять же из исходников vx=vx/1023.0, vy=vy/1023.0, vz=vz/513.0

Вроде бы делаю всё верно, а результат не тот  Sad



Модель получается в общем-то, можно рассмотреть геометрию (с горем по полам), но вершины сдвинуты в разные стороны
Если немного перемещать их получится это (хотя и грязненько, но это 3д модель точно Grin)



Буду рад любой подсказке или совету! Спасибо Smiley
Logged
Gildor
Administrator
Hero Member
*****
Posts: 7978



View Profile WWW
« Reply #1 on: May 13, 2015, 17:31 »

Привет.

Это следующий тип данных (скопирую код сюда для простоты, он небольшой)
Code:
struct FVectorIntervalFixed32GPU
{
int X:11, Y:11, Z:10;

FVector ToVector(const FVector &Mins, const FVector &Ranges) const
{
FVector r;
r.X = (X / 1023.0f) * Ranges.X + Mins.X;
r.Y = (Y / 1023.0f) * Ranges.Y + Mins.Y;
r.Z = (Z / 511.0f)  * Ranges.Z + Mins.Z;
return r;
}
};
Здесь идёт объявление "битовых полей", которые были ещё в языке C. Проблема следующая:
1) int и unsigned обрабатываются по-разному, отсюда и возможное смещение
2) упаковка данных в один 32-битный int может идти со старших или с младших разрядов

Ну и может ещё что. Когда я добавляю такие типы данных в UModel, то приходится перебором определять ответы на эти вопросы, пока всё не заработает (исходников-то у меня нет ...) Иногда помогает посмотреть в дизассемблере на свой же код и сравнить его с оригиналом.

Если нет возможности сделать знаковый/беззнаковый тип данных (int/unsigned), то надо добавлять смещение. Смещение - это половина диапазона, доступного для этого количества бит. Например, если число 10-битное, то диапазон будет 0..1023, ну а смещение соответственно будет 512. В данной структуре есть 10 и 11 битные величины.

Ну а в ToVector уже делается преобразование int в float (-1..+1) и затем пересчёт в Mins/Ranges.

Да, и ещё. Данный тип вектора не является спецификой PS3 - у Эпиков он есть и на XBox360. На PC почему-то упакованные позиции не используются.
Logged
elonir
Newbie
*
Posts: 26


View Profile
« Reply #2 on: May 14, 2015, 12:48 »

Ну а в ToVector уже делается преобразование int в float (-1..+1) и затем пересчёт в Mins/Ranges.

Ах, вот эту часть я по-видимому и пропускаю. Только что проверил, у меня все величины + Sad Ни одного значения x,y,z нет в минус -. Как реализуется эта функция ToVector? Это какая то типичная функция для С++?.

P.S. Значит у Эпиков это ещё и для Xbox используется, ага консольный формат такой  Wink Ну, просто отлично, что для PC такого нет (MOH2010 разве что?!), не дай бог!
Logged
Gildor
Administrator
Hero Member
*****
Posts: 7978



View Profile WWW
« Reply #3 on: May 14, 2015, 12:56 »

Ах, вот эту часть я по-видимому и пропускаю. Только что проверил, у меня все величины + Sad Ни одного значения x,y,z нет в минус -. Как реализуется эта функция ToVector? Это какая то типичная функция для С++?.
Вообще эта функция реализована в самом классе. И даже в моём ответе она есть.
Quote
P.S. Значит у Эпиков это ещё и для Xbox используется, ага консольный формат такой  Wink Ну, просто отлично, что для PC такого нет (MOH2010 разве что?!), не дай бог!
А чем плоха упаковка данных для освобождения памяти?
Logged
elonir
Newbie
*
Posts: 26


View Profile
« Reply #4 on: May 14, 2015, 13:20 »

Я понял, имеется ввиду эта часть  Wink   

r.X = (X / 1023.0f)
r.Y = (Y / 1023.0f)
r.Z = (Z / 511.0f)

Где то у меня закралась ошибка, буду разбираться (вы ранее писали возможные причины этого, видимо так и есть)! Упаковка данных точно не плоха для самой игры или для разработчиков Smiley Это я со своей колокольни, своё субъективное мнение сказал - поскольку для меня это пока тёмный лес, и если он таким и останется лучше было бы, что бы "packed" пореже использовался Grin Вот такая эгоистичная позиция получилась аха
Logged
Gildor
Administrator
Hero Member
*****
Posts: 7978



View Profile WWW
« Reply #5 on: May 14, 2015, 13:23 »

Ну, для кого-то вообще идеальный формат - XML Smiley И многие разработчики которые его используют, недоумевают - почему всё работает медленно и потребляет столько памяти.
Logged
elonir
Newbie
*
Posts: 26


View Profile
« Reply #6 on: May 14, 2015, 18:51 »

Да, это так верно подмечено Grin Гилдор, скажите пожалуйста, а насколько вы делаете бит сдвиг/бит или и тд. для x,y,z? В функции подробно этого не видно, я тут проделал потрясающий трюк и узнал, что проблема в том, что я изначально получаю не совсем верные x,y и z координаты (видимо не верно читаю 11,11,10 бит из 32 ).
Logged
Gildor
Administrator
Hero Member
*****
Posts: 7978



View Profile WWW
« Reply #7 on: May 14, 2015, 18:55 »

В том-то и дело что я сам ничего не сдвигаю - компилятор делает это за меня. Поэтому ...
Иногда помогает посмотреть в дизассемблере на свой же код и сравнить его с оригиналом.
Logged
elonir
Newbie
*
Posts: 26


View Profile
« Reply #8 on: May 14, 2015, 19:17 »

Да удобно конечно, ну теперь я хоть точно знаю где ошибка. Придётся как то додуматься до правильного решения Grin
Но принцип сам я хоть понимаю правильно? Дается 32 битное число - первые 11 бит - это X, следующие 11 бит это - Y, ну и последние 10 бит этого числа это Z. Я много раз проверял по-битно числа, которые получаются у  меня и вроде бы всё верно, да не тут то было  Grin
Logged
Gildor
Administrator
Hero Member
*****
Posts: 7978



View Profile WWW
« Reply #9 on: May 15, 2015, 19:56 »

(отделил вопросы по сборке UModel - http://www.gildor.org/smf/index.php/topic,2721.0.html)
Logged
elonir
Newbie
*
Posts: 26


View Profile
« Reply #10 on: May 16, 2015, 00:06 »

Гилдор скажите, а о чём говорит эта ошибка?

Code:
FFileReader:
:Serialize:File=ASSET_94DAF737_SF.XXX <- TArray:
:SerializeSimple <- TRawArray<< <- FSkelIndexBuffer3<< <- FStaticLODModel3<< <- TArray:
:Serialize:0/1 <- USkeletalMesh3:
:Serialize <- LoadObject:SkeletalMesh3'ASSET_94DAF737_SF.WP_1P_MI_HMG_SKM', pos=43417, ver=707/30, game=8000 <- UObject:
:EndLoad <-
Logged
Gildor
Administrator
Hero Member
*****
Posts: 7978



View Profile WWW
« Reply #11 on: May 16, 2015, 01:00 »

Сообщение об ошибке обрезано, есть только call stack.
Ну а вообще, смысл здесь в том, что
1) "game=8000" означает, что либо игра не распозналась, либо UModel про неё не знает, либо это стандартный UE3
2) перед чтением структуры FSkelIndexBuffer3 были какие-то данные, которые были прочитаны неверно (что-то изменено в формате), или же сама структура FSkelIndexBuffer3 была изменена разработчиками.
Logged
elonir
Newbie
*
Posts: 26


View Profile
« Reply #12 on: May 16, 2015, 01:13 »

Это очередная игра с "Packed" вершинами Smiley Странно, Umodel должен был её распознать это Dust 514.
Кстати, здесь не используется Sony SDK edge compression (во всяком случае в версии которую я скачал), значит можно сделать её поддержу в Umodel'e с скелетал и статик моделями Grin
Logged
Gildor
Administrator
Hero Member
*****
Posts: 7978



View Profile WWW
« Reply #13 on: May 16, 2015, 01:20 »

Для Dust 514 в UModel код распознавания следующий:
Code:
#if DUST514
if (ArVer == 708 && ArLicenseeVer == 35) SET(GAME_Dust514);
#endif
а у вас пакет версии 707/30. Возможно мне не дали дамп из "scan package versions" (или pkgtool), поэтому UModel про неё не знает. В таких случаях нужен ключик -game=...

Edge compression вроде используется для массивов индексов, не для вершин (на нём и упало).

Logged
elonir
Newbie
*
Posts: 26


View Profile
« Reply #14 on: May 16, 2015, 01:25 »

Да я знаю Edge compression для индексов, и здесь его нет  Smiley Массив индексов обычный как во множестве игр. Если вдруг будет желание могу сбросить файлики/пакеты.
Logged
Print 
« previous next »
Jump to:  

Powered by SMF | SMF © 2006-2009, Simple Machines LLC
Leviathan design by Bloc | XHTML | CSS