had messed up split skins

This commit is contained in:
aap 2016-07-10 12:48:04 +02:00
parent f4f4c088ff
commit b1e55a7784
3 changed files with 47 additions and 23 deletions

View File

@ -85,8 +85,8 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
Skin *skin = new Skin; Skin *skin = new Skin;
*PLUGINOFFSET(Skin*, geometry, offset) = skin; *PLUGINOFFSET(Skin*, geometry, offset) = skin;
// numUsedBones and numWeights appear in/after 34003 but not in/before 33002 // numUsedBones and numWeights appear in/after 34003
// (probably rw::version >= 0x34000) // but not in/before 33002 (probably rw::version >= 0x34000)
bool oldFormat = header[1] == 0; bool oldFormat = header[1] == 0;
// Use numBones for numUsedBones to allocate data // Use numBones for numUsedBones to allocate data

View File

@ -148,13 +148,24 @@ struct Skin
uint8 *indices; uint8 *indices;
float *weights; 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 boneLimit;
int32 numMeshes; int32 numMeshes;
int32 numRLE; int32 rleSize;
int8 *remapIndices; int8 *remapIndices;
int16 *RLEcount; RLEcount *rleCount;
int16 *RLE; RLE *rle;
uint8 *data; // only used by delete uint8 *data; // only used by delete
void *platformData; // a place to store platform specific stuff void *platformData; // a place to store platform specific stuff

View File

@ -61,7 +61,8 @@ copySkin(void *dst, void *src, int32 offset, int32)
dstskin->numWeights = srcskin->numWeights; dstskin->numWeights = srcskin->numWeights;
assert(0 && "can't copy skin yet"); 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->usedBones, srcskin->usedBones, srcskin->numUsedBones);
memcpy(dstskin->inverseMatrices, srcskin->inverseMatrices, memcpy(dstskin->inverseMatrices, srcskin->inverseMatrices,
srcskin->numBones*64); srcskin->numBones*64);
@ -78,15 +79,16 @@ readSkinSplitData(Stream *stream, Skin *skin)
skin->boneLimit = stream->readI32(); skin->boneLimit = stream->readI32();
skin->numMeshes = stream->readI32(); skin->numMeshes = stream->readI32();
skin->numRLE = stream->readI32(); skin->rleSize = stream->readI32();
sz = skin->numBones + 2*(skin->numMeshes+skin->numRLE); if(skin->numMeshes){
if(sz != 0){ sz = skin->numBones + 2*(skin->numMeshes+skin->rleSize);
data = (int8*)malloc(sz); data = (int8*)malloc(sz);
stream->read(data, sz); stream->read(data, sz);
skin->remapIndices = data; skin->remapIndices = data;
skin->RLEcount = (int16*)(data + skin->numBones); skin->rleCount = (Skin::RLEcount*)(data + skin->numBones);
skin->RLE = (int16*)(data + skin->numBones + 2*skin->numMeshes); skin->rle = (Skin::RLE*)(data + skin->numBones + 2*skin->numMeshes);
} }
return stream;
} }
Stream* Stream*
@ -94,15 +96,19 @@ writeSkinSplitData(Stream *stream, Skin *skin)
{ {
stream->writeI32(skin->boneLimit); stream->writeI32(skin->boneLimit);
stream->writeI32(skin->numMeshes); stream->writeI32(skin->numMeshes);
stream->writeI32(skin->numRLE); stream->writeI32(skin->rleSize);
stream->write(skin->remapIndices, if(skin->numMeshes)
skin->numBones + 2*(skin->numMeshes+skin->numRLE)); stream->write(skin->remapIndices,
skin->numBones + 2*(skin->numMeshes+skin->rleSize));
return stream;
} }
int32 int32
skinSplitDataSize(Skin *skin) 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* 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; Skin *skin = new Skin;
*PLUGINOFFSET(Skin*, geometry, offset) = skin; *PLUGINOFFSET(Skin*, geometry, offset) = skin;
// numUsedBones and numWeights appear in/after 34003 but not in/before 33002 // numUsedBones and numWeights appear in/after 34003
// (probably rw::version >= 0x34000) // but not in/before 33002 (probably rw::version >= 0x34000)
bool oldFormat = header[1] == 0; 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) if(oldFormat)
skin->init(header[0], header[0], geometry->numVertices); skin->init(header[0], header[0], geometry->numVertices);
else else
@ -312,14 +320,19 @@ Skin::init(int32 numBones, int32 numUsedBones, int32 numVertices)
this->boneLimit = 0; this->boneLimit = 0;
this->numMeshes = 0; this->numMeshes = 0;
this->numRLE = 0; this->rleSize = 0;
this->remapIndices = nil; this->remapIndices = nil;
this->RLEcount = nil; this->rleCount = nil;
this->RLE = nil; this->rle = nil;
this->platformData = nil; this->platformData = nil;
} }
static_assert(sizeof(Skin::RLEcount) == 2, "RLEcount size");
static_assert(sizeof(Skin::RLE) == 2, "RLE size");
void void
Skin::findNumWeights(int32 numVertices) Skin::findNumWeights(int32 numVertices)
{ {