skin split streaming

This commit is contained in:
aap 2016-07-09 12:24:26 +02:00
parent bd06c54c57
commit f4f4c088ff
6 changed files with 83 additions and 35 deletions

View File

@ -195,6 +195,9 @@ calczShiftScale(Camera *cam)
float32 f = cam->farPlane;
float32 N = engine->zNear;
float32 F = engine->zFar;
// RW does this
N += (F - N)/10000.0f;
F -= (F - N)/10000.0f;
if(cam->projection == Camera::PERSPECTIVE){
cam->zScale = (N - F)*n*f/(f - n);
cam->zShift = (F*f - N*n)/(f - n);

View File

@ -65,8 +65,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
stream->read(natskin->vertexBuffer, size);
stream->read(skin->inverseMatrices, skin->numBones*64);
// no split skins in GTA
stream->seek(12);
readSkinSplitData(stream, skin);
return stream;
}
@ -91,8 +90,8 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
stream->write(natskin->vertexBuffer,
geometry->numVertices*natskin->stride);
stream->write(skin->inverseMatrices, skin->numBones*64);
int32 buffer[3] = { 0, 0, 0};
stream->write(buffer, 12);
writeSkinSplitData(stream, skin);
return stream;
}
@ -107,7 +106,8 @@ getSizeNativeSkin(void *object, int32 offset)
return -1;
NativeSkin *natskin = (NativeSkin*)skin->platformData;
return 12 + 8 + 2*256*4 + 4*4 +
natskin->stride*geometry->numVertices + skin->numBones*64 + 12;
natskin->stride*geometry->numVertices + skin->numBones*64 +
skinSplitDataSize(skin);
}
void

View File

@ -108,10 +108,12 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
skin->usedBones[i] = i;
}
if(!oldFormat)
// last 3 ints are split data as in the other formats
// TODO: what are the other 4?
stream->seek(7*4);
if(!oldFormat){
// TODO: what is this?
stream->seek(4*4);
readSkinSplitData(stream, skin);
}
return stream;
}
@ -140,8 +142,10 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
stream->write(skin->usedBones, skin->numUsedBones);
stream->write(skin->inverseMatrices, skin->numBones*64);
if(!oldFormat){
uint32 buffer[7] = { 0, 0, 0, 0, 0, 0, 0 };
stream->write(buffer, 7*4);
uint32 buffer[4] = { 0, 0, 0, 0, };
stream->write(buffer, 4*4);
writeSkinSplitData(stream, skin);
}
return stream;
}
@ -155,7 +159,7 @@ getSizeNativeSkin(void *object, int32 offset)
int32 size = 12 + 4 + 4 + skin->numBones*64;
// not sure which version introduced the new format
if(version >= 0x34000)
size += skin->numUsedBones + 16 + 12;
size += skin->numUsedBones + 16 + skinSplitDataSize(skin);
return size;
}

View File

@ -147,6 +147,15 @@ struct Skin
float *inverseMatrices;
uint8 *indices;
float *weights;
// split data; not sure what RLE is exactly
int32 boneLimit;
int32 numMeshes;
int32 numRLE;
int8 *remapIndices;
int16 *RLEcount;
int16 *RLE;
uint8 *data; // only used by delete
void *platformData; // a place to store platform specific stuff
@ -162,6 +171,9 @@ struct SkinGlobals
ObjPipeline *pipelines[NUM_PLATFORMS];
};
extern SkinGlobals skinGlobals;
Stream *readSkinSplitData(Stream *stream, Skin *skin);
Stream *writeSkinSplitData(Stream *stream, Skin *skin);
int32 skinSplitDataSize(Skin *skin);
void registerSkinPlugin(void);
}

View File

@ -38,6 +38,7 @@ destroySkin(void *object, int32 offset, int32)
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
if(skin){
delete[] skin->data;
free(skin->remapIndices);
// delete[] skin->platformData;
}
delete skin;
@ -69,6 +70,41 @@ copySkin(void *dst, void *src, int32 offset, int32)
return dst;
}
Stream*
readSkinSplitData(Stream *stream, Skin *skin)
{
uint32 sz;
int8 *data;
skin->boneLimit = stream->readI32();
skin->numMeshes = stream->readI32();
skin->numRLE = stream->readI32();
sz = skin->numBones + 2*(skin->numMeshes+skin->numRLE);
if(sz != 0){
data = (int8*)malloc(sz);
stream->read(data, sz);
skin->remapIndices = data;
skin->RLEcount = (int16*)(data + skin->numBones);
skin->RLE = (int16*)(data + skin->numBones + 2*skin->numMeshes);
}
}
Stream*
writeSkinSplitData(Stream *stream, Skin *skin)
{
stream->writeI32(skin->boneLimit);
stream->writeI32(skin->numMeshes);
stream->writeI32(skin->numRLE);
stream->write(skin->remapIndices,
skin->numBones + 2*(skin->numMeshes+skin->numRLE));
}
int32
skinSplitDataSize(Skin *skin)
{
return 12 + skin->numBones + 2*(skin->numMeshes+skin->numRLE);
}
static Stream*
readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
{
@ -114,18 +150,6 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
if(oldFormat)
stream->seek(4); // skip 0xdeaddead
stream->read(&skin->inverseMatrices[i*16], 64);
//{
//float *mat = &skin->inverseMatrices[i*16];
//printf("[ [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
// " [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
// " [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
// " [ %8.4f, %8.4f, %8.4f, %8.4f ] ]\n",
// mat[0], mat[4], mat[8], mat[12],
// mat[1], mat[5], mat[9], mat[13],
// mat[2], mat[6], mat[10], mat[14],
// mat[3], mat[7], mat[11], mat[15]);
//}
}
if(oldFormat){
@ -133,9 +157,9 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
skin->findUsedBones(geometry->numVertices);
}
// no split skins in GTA
if(!oldFormat)
stream->seek(12);
readSkinSplitData(stream, skin);
return stream;
}
@ -181,11 +205,8 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
stream->write(&skin->inverseMatrices[i*16], 64);
}
// no split skins in GTA
if(!oldFormat){
uint32 buffer[3] = { 0, 0, 0};
stream->write(buffer, 12);
}
if(!oldFormat)
writeSkinSplitData(stream, skin);
return stream;
}
@ -218,7 +239,7 @@ getSizeSkin(void *object, int32 offset, int32)
if(version < 0x34000)
size += skin->numBones*4;
else
size += skin->numUsedBones + 12;
size += skin->numUsedBones + skinSplitDataSize(skin);
return size;
}
@ -289,6 +310,13 @@ Skin::init(int32 numBones, int32 numUsedBones, int32 numVertices)
if(numVertices)
this->weights = (float*)p;
this->boneLimit = 0;
this->numMeshes = 0;
this->numRLE = 0;
this->remapIndices = nil;
this->RLEcount = nil;
this->RLE = nil;
this->platformData = nil;
}

View File

@ -129,9 +129,10 @@ main(int argc, char *argv[])
s.open(argv[1], "rb");
ChunkHeaderInfo header;
readChunkHeaderInfo(&s, &header);
while(readChunkHeaderInfo(&s, &header)){
if(argc == 2)
readchunk(&s, &header, 0);
}
printf("%x %x %x\n", header.version, header.build,
libraryIDPack(header.version, header.build));