Не нужно ничего копать, всё уже расписно в официальных доках по RenderWare

И вообще, зачем смотреть лавочки и светофоры, если тот же транспорт - это иделальный пример модели с иерархией.
Искать "компонент" можно по индексу в иерархии или по его названию.
Но тут ещё нужно учесть то, что игра изначально разделяет понятия статической (без иерархии) и динамической (с иерархией) модели.
Если ты попытаешься загрузить транспорт как статический обьект (допустим, пропишешь его в секции objs), то никакой иерархии у тебя не будет.
Интересная вешь: статика в VC (и, может быть, вообще в GTA 3-ей эры) может хранить как максимум 3 атомика. Как я понял, они играют роль лодов.
Порядок атомиков определяется окончанием в названии фрейма
_L%
А если засунуть в dff несколько атомиков, и прицепить их к фреймам без этого окончания - по идее, случится утечка памяти (все атомики будут сохраняться в одно место (перезаписываться, без удаления).
bool CFileLoader::LoadAtomicFile(int stream, int modelIndex) {
if ( RwStreamFindChunk(stream, 16, 0, 0)) { // ВО ВСЕХ ДФФ ИЗНАЧАЛЬНО ЕСТЬ КЛАМП (А ЗНАЧИТ И ИЕРАРХИЯ)
RpClump *clump = RpClumpStreamRead(stream);
if ( !clump )
return false;
// НО ЗАЧЕМ НАМ ИЕРЕРХИЯ, ЕСЛИ ЭТО СТАТИЧЕСКАЯ МОДЕЛЬ?
pSaveModelInfo = CModelInfo::ms_modelInfoPtrs[modelIndex];
// МЫ НАХОДИМ И СОХРАНЯЕМ АТОМИКИ
// ЕСЛИ У НАЗВАНИЯ ФРЕЙМА ЕСТЬ ОКОНЧАНИЕ _LX -
// СОХРАНЯЕМ АТОМИК В СЛОТ X
// ЕСЛИ НЕТУ - В СЛОТ 0
// ВСЕГО 3 СЛОТА
RpClumpForAllAtomics(clump, CFileLoader::SetRelatedModelInfoCB, clump);
// А ВСЁ ОСТАЛЬНОЕ УДАЛЯЕМ, В Т.Ч. И САМ КЛАМП
RpClumpDestroy(clump);
// ТЕПЕРЬ У НАС НЕТУ ИЕРЕРАРХИИ, ЕСТЬ ТОЛЬКО 3 АТОМИКА, КОТОРЫЕ ПРИЦЕПЛЕНЫ К ФРЕЙМАМ В НУЛЕВЫХ КООРДИНАТАХ
}
return true;
}
Этот коллбэк выполняется для всех атомиков, которые есть в клампе
RpAtomic *CFileLoader::SetRelatedModelInfoCB(RpAtomic *atomic, RpClump *clump) {
char *frameName = GetFrameNodeName(atomic->object.parent);// получаем имя фрейма, к которому прицеплен атомик
char resultName[24]; int number;
GetNameAndLOD(frameName , resultName, &number); // получаем индекс атомика по его имени (_LX)
CVisibilityPlugins::SetAtomicRenderCallback(atomic, 0);
pSaveModelInfo->SetAtomic(number, atomic);// сохраняем атомик в слот X
RpClumpRemoveAtomic(clump, atomic); // удаляем атомик из основной иерархии
RwFrame *newFrame = RwFrameCreate(); // создаём новый фрейм
RpAtomicSetFrame(atomic, frame); // и цепляем к нему атомик
CVisibilityPlugins::SetAtomicModelInfo(atomic, pSaveModelInfo);
return atomic;
}
Заметьте, что новосозданный фрейм никак не связан с тем, к которому изначально был прикреплен атомик.
Т.е. получается, если ваш атомик был в иерархии смещён на какую-то дистанцию относительно центра, напр.
parentFrame---------atomic1 (0.0;0.0;0.0)
|
childFrame_L1-------atomic2 (0.0;0.0;1.0)
То после загрузки
оба атомика буду расположены по координатам (0.0;0.0;0.0).