diff --git a/src/ps2/ps2skin.cpp b/src/ps2/ps2skin.cpp index 1750c39..2e2c46c 100644 --- a/src/ps2/ps2skin.cpp +++ b/src/ps2/ps2skin.cpp @@ -85,8 +85,8 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset) Skin *skin = new Skin; *PLUGINOFFSET(Skin*, geometry, offset) = skin; - // numUsedBones and numWeights appear in/after 34003 but not in/before 33002 - // (probably rw::version >= 0x34000) + // numUsedBones and numWeights appear in/after 34003 + // but not in/before 33002 (probably rw::version >= 0x34000) bool oldFormat = header[1] == 0; // Use numBones for numUsedBones to allocate data diff --git a/src/rwplugins.h b/src/rwplugins.h index adf2dd2..b5d1a8e 100644 --- a/src/rwplugins.h +++ b/src/rwplugins.h @@ -148,13 +148,24 @@ struct Skin uint8 *indices; float *weights; - // split data; not sure what RLE is exactly + // split skin + + // points into rle for each mesh + struct RLEcount { + uint8 start; + uint8 size; + }; + // run length encoded used bones + struct RLE { + uint8 startbone; // into remapIndices + uint8 n; + }; int32 boneLimit; int32 numMeshes; - int32 numRLE; + int32 rleSize; int8 *remapIndices; - int16 *RLEcount; - int16 *RLE; + RLEcount *rleCount; + RLE *rle; uint8 *data; // only used by delete void *platformData; // a place to store platform specific stuff diff --git a/src/skin.cpp b/src/skin.cpp index 1ca5d93..a58c519 100644 --- a/src/skin.cpp +++ b/src/skin.cpp @@ -61,7 +61,8 @@ copySkin(void *dst, void *src, int32 offset, int32) dstskin->numWeights = srcskin->numWeights; assert(0 && "can't copy skin yet"); - dstskin->init(srcskin->numBones, srcskin->numUsedBones, geometry->numVertices); + dstskin->init(srcskin->numBones, srcskin->numUsedBones, + geometry->numVertices); memcpy(dstskin->usedBones, srcskin->usedBones, srcskin->numUsedBones); memcpy(dstskin->inverseMatrices, srcskin->inverseMatrices, srcskin->numBones*64); @@ -78,15 +79,16 @@ readSkinSplitData(Stream *stream, Skin *skin) skin->boneLimit = stream->readI32(); skin->numMeshes = stream->readI32(); - skin->numRLE = stream->readI32(); - sz = skin->numBones + 2*(skin->numMeshes+skin->numRLE); - if(sz != 0){ + skin->rleSize = stream->readI32(); + if(skin->numMeshes){ + sz = skin->numBones + 2*(skin->numMeshes+skin->rleSize); 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); + skin->rleCount = (Skin::RLEcount*)(data + skin->numBones); + skin->rle = (Skin::RLE*)(data + skin->numBones + 2*skin->numMeshes); } + return stream; } Stream* @@ -94,15 +96,19 @@ 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)); + stream->writeI32(skin->rleSize); + if(skin->numMeshes) + stream->write(skin->remapIndices, + skin->numBones + 2*(skin->numMeshes+skin->rleSize)); + return stream; } int32 skinSplitDataSize(Skin *skin) { - return 12 + skin->numBones + 2*(skin->numMeshes+skin->numRLE); + if(skin->numMeshes == 0) + return 12; + return 12 + skin->numBones + 2*(skin->numMeshes+skin->rleSize); } static Stream* @@ -125,15 +131,17 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32) } } - stream->read(header, 4); // numBones, numUsedBones, numWeights, unused + stream->read(header, 4); // numBones, numUsedBones, + // numWeights, unused Skin *skin = new Skin; *PLUGINOFFSET(Skin*, geometry, offset) = skin; - // numUsedBones and numWeights appear in/after 34003 but not in/before 33002 - // (probably rw::version >= 0x34000) + // numUsedBones and numWeights appear in/after 34003 + // but not in/before 33002 (probably rw::version >= 0x34000) bool oldFormat = header[1] == 0; - // Use numBones for numUsedBones to allocate data, find out the correct value later + // Use numBones for numUsedBones to allocate data, + // find out the correct value later if(oldFormat) skin->init(header[0], header[0], geometry->numVertices); else @@ -312,14 +320,19 @@ Skin::init(int32 numBones, int32 numUsedBones, int32 numVertices) this->boneLimit = 0; this->numMeshes = 0; - this->numRLE = 0; + this->rleSize = 0; this->remapIndices = nil; - this->RLEcount = nil; - this->RLE = nil; + this->rleCount = nil; + this->rle = nil; this->platformData = nil; } + + +static_assert(sizeof(Skin::RLEcount) == 2, "RLEcount size"); +static_assert(sizeof(Skin::RLE) == 2, "RLE size"); + void Skin::findNumWeights(int32 numVertices) {