ACE3/extensions/common/p3d/parser_ref.txt

269 lines
15 KiB
Plaintext

#pragma once
#include "ace_common.h"
#include "p3d/parser.hpp"
#include "p3d/model.hpp"
#include <fstream>
#include <lzo/minilzo.h>
namespace ace {
namespace p3d {
parser::parser() {}
parser::~parser() {}
model * parser::load(const std::string filepath) {
std::ifstream ifstream;
model *_model = new model();
size_t index = 4;
_model->filepath = filepath;
ifstream.open(filepath, std::ios::binary);
if (!ifstream.good()) {
printf("! File not found\n");
return false;
}
// get length of file:
ifstream.seekg(0, std::ios::end);
_model->size = ifstream.tellg();
ifstream.seekg(0, std::ios::beg);
// Read the whole file into memory real fast
_model->raw = new unsigned char[_model->size];
ifstream.read((char *)_model->raw, _model->size);
// use the ifstream to read the data
ifstream.seekg(0, std::ios::beg);
ifstream.read((char *)&_model->header.filetype, 4);
ifstream.read((char *)&_model->header.version, sizeof(uint64_t));
// If version > 48, it may have a path or a empty null byte.
if (_model->header.version >= 48) {
for (int x = 0; x < sizeof(_model->header.prefix); x++) {
char byte;
ifstream.read(&byte, 1);
_model->header.prefix[x] = byte;
if (byte == 0x00) break;
}
}
ifstream.read((char *)&_model->header.lod_count, sizeof(uint32_t));
printf("Version: %d\n", _model->header.version);
printf("%s\n", _model->header.prefix);
printf("\tLODs:\t%d\n", (long long)_model->header.lod_count);
#ifdef _DEBUG
#define READ_DATA(stream, output, size) stream.read((char *)&output, size);
#else
#define READ_DATA(stream, output, size) stream.read((char *)&output, size);
#endif
#define PRINT_INDEX { std::streamoff pos = ifstream.tellg(); printf("Current Index: %08x\n", pos); }
// Begin model info
READ_DATA(ifstream, _model->info.LodResolutions, sizeof(float)*_model->header.lod_count);
READ_DATA(ifstream, _model->info.Index, sizeof(uint32_t));
READ_DATA(ifstream, _model->info.MemLodSphere, sizeof(float));
READ_DATA(ifstream, _model->info.GeoLodSphere, sizeof(float));
READ_DATA(ifstream, _model->info.PointFlags, sizeof(uint32_t)*3);
READ_DATA(ifstream, _model->info.Offset1, sizeof(XYZTriplet));
READ_DATA(ifstream, _model->info.mapIconColor, sizeof(uint32_t));
READ_DATA(ifstream, _model->info.mapSelectedColor, sizeof(uint32_t));
READ_DATA(ifstream, _model->info.ViewDensity, sizeof(float));
READ_DATA(ifstream, _model->info.bboxMinPosition, sizeof(XYZTriplet));
READ_DATA(ifstream, _model->info.bboxMaxPosition, sizeof(XYZTriplet));
READ_DATA(ifstream, _model->info.CentreOfGravity, sizeof(XYZTriplet));
READ_DATA(ifstream, _model->info.Offset2, sizeof(XYZTriplet));
READ_DATA(ifstream, _model->info.CogOffset, sizeof(XYZTriplet));
READ_DATA(ifstream, _model->info.ModelMassVectors, sizeof(XYZTriplet)*3);
READ_DATA(ifstream, _model->info.ThermalProfile2, sizeof(uint8_t)*24);
READ_DATA(ifstream, _model->info.AutoCenter, sizeof(uint8_t));
READ_DATA(ifstream, _model->info.lockAutoCenter, sizeof(uint8_t));
READ_DATA(ifstream, _model->info.canOcclude, sizeof(uint8_t));
READ_DATA(ifstream, _model->info.canBeOccluded, sizeof(uint8_t));
READ_DATA(ifstream, _model->info.allowAnimation, sizeof(uint8_t));
READ_DATA(ifstream, _model->info.UnknownARMAFlags, sizeof(uint8_t) * 6);
READ_DATA(ifstream, _model->info.ThermalProfile, sizeof(uint8_t) * 24);
READ_DATA(ifstream, _model->info.UnknownLong, sizeof(uint32_t));
// Skeleton!
for (int x = 0; x < sizeof(_model->info.Skeleton); x++) {
char byte;
ifstream.read(&byte, 1);
_model->info.Skeleton.name[x] = byte;
if (byte == 0x00) break;
}
if (_model->info.Skeleton.name[0] != 0x00) {
READ_DATA(ifstream, _model->info.Skeleton.isInherited, sizeof(uint8_t));
READ_DATA(ifstream, _model->info.Skeleton.bone_count, sizeof(uint32_t));
for (int x = 0; x < 256 && x < _model->info.Skeleton.bone_count; x++) {
for (int y = 0; y < sizeof(_model->info.Skeleton.bone_names[x].BoneName); y++) {
char byte;
ifstream.read(&byte, 1);
_model->info.Skeleton.bone_names[x].BoneName[y] = byte;
if (byte == 0x00) break;
}
for (int y = 0; y < sizeof(_model->info.Skeleton.bone_names[x].ParentBoneName); y++) {
char byte;
ifstream.read(&byte, 1);
_model->info.Skeleton.bone_names[x].ParentBoneName[y] = byte;
if (byte == 0x00) break;
}
printf("Read bone entry: %s -> Parent:%s\n", _model->info.Skeleton.bone_names[x].BoneName, _model->info.Skeleton.bone_names[x].ParentBoneName);
}
}
READ_DATA(ifstream, _model->info.UnknownByte, sizeof(uint8_t));
READ_DATA(ifstream, _model->info.nFloats, sizeof(uint32_t));
printf("Floats: %d\n", _model->info.nFloats);
if (_model->info.nFloats * sizeof(float) > 1024) {
// TODO!: Read compressed segment
} else {
ifstream.seekg(_model->info.nFloats*sizeof(float), ifstream.cur);
//READ_DATA(ifstream, _model->info.UnknownFloats, );
}
READ_DATA(ifstream, _model->info.Mass, sizeof(float));
READ_DATA(ifstream, _model->info.MassReciprocal, sizeof(float));
READ_DATA(ifstream, _model->info.AltMass, sizeof(float));
READ_DATA(ifstream, _model->info.AltMassReciprocal, sizeof(float));
READ_DATA(ifstream, _model->info.UnknownByteIndices, sizeof(uint8_t) * 14);
READ_DATA(ifstream, _model->info.UnknownShort, sizeof(uint16_t));
READ_DATA(ifstream, _model->info.UnknownLodCount, sizeof(uint32_t));
READ_DATA(ifstream, _model->info.UnknownBool, sizeof(uint8_t));
/*
for (int x = 0; x < sizeof(_model->info.ClassType); x++) {
char byte;
ifstream.read(&byte, 1);
_model->info.ClassType[x] = byte;
if (byte == 0x00 || byte == 0xff) break;
}
for (int x = 0; x < sizeof(_model->info.DestructType); x++) {
char byte;
ifstream.read(&byte, 1);
_model->info.DestructType[x] = byte;
if (byte == 0x00 || byte == 0xff) break;
}*/
READ_DATA(ifstream, _model->info.UnknownBool2, sizeof(uint8_t));
READ_DATA(ifstream, _model->info.Always0, sizeof(uint8_t));
for (int x = 0; x < sizeof(_model->header.lod_count); x++) {
READ_DATA(ifstream, _model->info.DefaultIndicators[x], sizeof(uint8_t)*12);
}
// Read ahead because i dont understand whats going on
for (int x = 0; x < _model->size; x++) {
char byte;
ifstream.read(&byte, 1);
if (byte != -1) {
ifstream.seekg(-1, ifstream.cur);
break;
};
}
READ_DATA(ifstream, _model->animations.AnimsExist, sizeof(uint8_t));
if (_model->animations.AnimsExist) {
READ_DATA(ifstream, _model->animations.nAnimationClasses, sizeof(uint32_t));
printf("Animations: %d", _model->animations.nAnimationClasses);
for (int n = 0; n < _model->animations.nAnimationClasses; n++) {
READ_DATA(ifstream, _model->animations.AnimationClasses[n].AnimTransformType, sizeof(uint32_t));
for (int x = 0; x < sizeof(_model->animations.AnimationClasses[n].AnimClassName); x++) {
char byte;
ifstream.read(&byte, 1);
_model->animations.AnimationClasses[n].AnimClassName[x] = byte;
if (byte == 0x00) break;
}
for (int x = 0; x < sizeof(_model->animations.AnimationClasses[n].AnimSource); x++) {
char byte;
ifstream.read(&byte, 1);
_model->animations.AnimationClasses[n].AnimSource[x] = byte;
if (byte == 0x00) break;
}
printf("Reading animation: [%08x]-[%s]-%s\n", _model->animations.AnimationClasses[n].AnimTransformType, _model->animations.AnimationClasses[n].AnimClassName, _model->animations.AnimationClasses[n].AnimSource);
READ_DATA(ifstream, _model->animations.AnimationClasses[n].MinMaxValue, sizeof(float) * 2);
READ_DATA(ifstream, _model->animations.AnimationClasses[n].MinMaxPhase, sizeof(float) * 2);
READ_DATA(ifstream, _model->animations.AnimationClasses[n].sourceAddress, sizeof(uint32_t));
READ_DATA(ifstream, _model->animations.AnimationClasses[n].Always0, sizeof(uint32_t));
READ_DATA(ifstream, _model->animations.AnimationClasses[n].nFloats, sizeof(uint32_t));
for (int x = 0; x < _model->animations.AnimationClasses[n].nFloats; x++) {
READ_DATA(ifstream, _model->animations.AnimationClasses[n].floats, sizeof(float));
}
READ_DATA(ifstream, _model->animations.AnimationClasses[n].value, sizeof(float));
switch (_model->animations.AnimationClasses[n].AnimTransformType) {
case 0:READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float)); break;//rotaton
case 1:READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float)); break;//rotationX
case 2:READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float)); break;//rotationY
case 3:READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float)); break;//rotationZ
READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float) * 2);
break;
case 4:READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float)); break;//translation
case 5:READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float)); break;//translationX
case 6:READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float)); break;//translationY
case 7:READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float)); break; //translationZ
READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float)*2);
break;
case 8: //"direct"
READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float) * 8);
break;
case 9: //"hide"
READ_DATA(ifstream, _model->animations.AnimationClasses[n].data, sizeof(float));
break;
default:
READ_DATA(ifstream, _model->animations.AnimationClasses[n].value, sizeof(float));
}
PRINT_INDEX;
}
}
// Animations done, WEEE!
READ_DATA(ifstream, _model->animations.NoOfResolutions, sizeof(uint32_t));
for (int x = 0; x < _model->animations.NoOfResolutions; x++) {
// Read a Bones2Anims entry
READ_DATA(ifstream, _model->animations.Bones2Anims[x].NoOfBones, sizeof(uint32_t));
for (int y = 0; y < _model->animations.Bones2Anims[x].NoOfBones; y++) {
READ_DATA(ifstream, _model->animations.Bones2Anims[x].Bone2AnimClassLists[y].NoOfAnimClasses, sizeof(uint32_t));
for (int z = 0; z < _model->animations.Bones2Anims[x].Bone2AnimClassLists[y].NoOfAnimClasses; z++) {
READ_DATA(ifstream, _model->animations.Bones2Anims[x].Bone2AnimClassLists[y].AnimationClassIndex[z], sizeof(uint32_t));
}
}
}
for (int x = 0; x < _model->animations.NoOfResolutions; x++) {
// Read Anims2Bones
for (int y = 0; y < _model->animations.nAnimationClasses; y++) {
READ_DATA(ifstream, _model->animations.Anims2Bones[x].AnimBones[y].SkeletonBoneNameIndex, sizeof(uint32_t));
if (_model->animations.Anims2Bones[x].AnimBones[y].SkeletonBoneNameIndex != -1 && _model->animations.AnimationClasses[y].AnimTransformType != 8 && _model->animations.AnimationClasses[y].AnimTransformType != 9) {
READ_DATA(ifstream, _model->animations.Anims2Bones[x].AnimBones[y].axisPos, sizeof(float) * 3);
READ_DATA(ifstream, _model->animations.Anims2Bones[x].AnimBones[y].axisDir, sizeof(float) * 3);
}
PRINT_INDEX;
printf("Read bone index: %d\n", _model->animations.Anims2Bones[x].AnimBones[y].SkeletonBoneNameIndex);
}
}
READ_DATA(ifstream, _model->StartAddressOfLods, sizeof(uint32_t)*_model->header.lod_count);
READ_DATA(ifstream, _model->EndAddressOfLods, sizeof(uint32_t)*_model->header.lod_count);
printf("Beginning LOD Read: Start[%d] End[%d]\n", _model->StartAddressOfLods, _model->EndAddressOfLods);
return _model;
}
};
};