Implemented Breakable model and fixed bug in Extension stream read.

This commit is contained in:
Angelo Papenhoff 2014-12-24 23:52:03 +01:00
parent 5842f6221b
commit 7b4dd3a5ac
7 changed files with 136 additions and 8 deletions

View File

@ -17,6 +17,7 @@ main(int argc, char *argv[])
// Rw::Build = 0;
registerNodeNamePlugin();
registerBreakableModelPlugin();
registerNativeDataPlugin();
registerMeshPlugin();
Rw::Clump *c;

View File

@ -18,11 +18,21 @@ using namespace std;
namespace Rw {
namespace Gl {
// 20303 0 0 0 3 vertices: 3 float
// 53 1 0 0 2 texCoords: 2 floats
// 20043 1 3 0 2 texCoords: 2 shorts
// 6954 2 1 1 3 normal: 3 bytes normalized
// 13527 3 2 1 4 color: 4 ubytes normalized
// 196 4 2 1 4 weight: 4 ubytes normalized
// 225 4 4 1 4 weight: 4 ushorts normalized
// 421 5 2 0 4 indices: 4 ubytes
// 12887 6 2 1 4 extracolor:4 ubytes normalized
static void
printAttribInfo(AttribDesc *attribs, int n)
{
for(int i = 0; i < n; i++)
printf("%x %x %x %x %x %x\n",
printf("%x %x %x %x\n",
attribs[i].index,
attribs[i].type,
attribs[i].normalized,
@ -55,7 +65,7 @@ ReadNativeData(istream &stream, int32, void *object, int32, int32)
header->attribs = new AttribDesc[header->numAttribs];
stream.read((char*)header->attribs,
header->numAttribs*sizeof(AttribDesc));
// Any better way to find out the size? (header length can be wrong)
printAttribInfo(header->attribs, header->numAttribs);
header->dataSize = header->attribs[0].stride*geometry->numVertices;
header->data = new uint8[header->dataSize];
stream.read((char*)header->data, header->dataSize);

View File

@ -258,8 +258,119 @@ getSizeNativeData(void *object, int32 offset, int32 size)
void
registerNativeDataPlugin(void)
{
Geometry::registerPlugin(0, 0x510, NULL, destroyNativeData, NULL);
Geometry::registerPluginStream(0x510, (StreamRead)readNativeData,
Geometry::registerPlugin(0, ID_NATIVEDATA,
NULL, destroyNativeData, NULL);
Geometry::registerPluginStream(ID_NATIVEDATA,
(StreamRead)readNativeData,
(StreamWrite)writeNativeData,
(StreamGetSize)getSizeNativeData);
}
// Breakable Model
// TODO: put this in a header
struct Breakable
{
uint32 position;
uint32 numVertices;
uint32 numFaces;
uint32 numMaterials;
float32 *vertices;
float32 *texCoords;
uint8 *colors;
uint16 *faces;
uint16 *matIDs;
char (*texNames)[32];
char (*maskNames)[32];
float32 (*surfaceProps)[3];
};
static void*
destroyBreakableModel(void *object, int32 offset, int32 size)
{
uint8 *p = *PLUGINOFFSET(uint8*, object, offset);
delete[] p;
return object;
}
static void
readBreakableModel(istream &stream, int32 len, void *object, int32 o, int32 s)
{
uint32 header[13];
uint32 hasBreakable = readUInt32(stream);
if(hasBreakable == 0)
return;
stream.read((char*)header, 13*4);
uint32 size = header[1]*(12+8+4) + header[5]*(6+2) +
header[8]*(32+32+12);
uint8 *p = new uint8[sizeof(Breakable)+size];
Breakable *breakable = (Breakable*)p;
*PLUGINOFFSET(Breakable*, object, o) = breakable;
breakable->position = header[0];
breakable->numVertices = header[1];
breakable->numFaces = header[5];
breakable->numMaterials = header[8];
p += sizeof(Breakable);
stream.read((char*)p, size);
breakable->vertices = (float*)p;
p += breakable->numVertices*12;
breakable->texCoords = (float*)p;
p += breakable->numVertices*8;
breakable->colors = (uint8*)p;
p += breakable->numVertices*4;
breakable->faces = (uint16*)p;
p += breakable->numFaces*6;
breakable->matIDs = (uint16*)p;
p += breakable->numFaces*2;
breakable->texNames = (char(*)[32])p;
p += breakable->numMaterials*32;
breakable->maskNames = (char(*)[32])p;
p += breakable->numMaterials*32;
breakable->surfaceProps = (float32(*)[3])p;
}
static void
writeBreakableModel(ostream &stream, int32 len, void *object, int32 o, int32 s)
{
uint32 header[13];
Breakable *breakable = *PLUGINOFFSET(Breakable*, object, o);
uint8 *p = (uint8*)breakable;
if(breakable == NULL){
writeUInt32(0, stream);
return;
}
writeUInt32(1, stream);
memset((char*)header, 0, 13*4);
header[0] = breakable->position;
header[1] = breakable->numVertices;
header[5] = breakable->numFaces;
header[8] = breakable->numMaterials;
stream.write((char*)header, 13*4);
p += sizeof(Breakable);
stream.write((char*)p, breakable->numVertices*(12+8+4) +
breakable->numFaces*(6+2) +
breakable->numMaterials*(32+32+12));
}
static int32
getSizeBreakableModel(void *object, int32 offset, int32 size)
{
Breakable *breakable = *PLUGINOFFSET(Breakable*, object, offset);
if(breakable == NULL)
return 4;
return 56 + breakable->numVertices*(12+8+4) +
breakable->numFaces*(6+2) +
breakable->numMaterials*(32+32+12);
}
void
registerBreakableModelPlugin(void)
{
Geometry::registerPlugin(sizeof(Breakable*), ID_BREAKABLE, NULL,
destroyBreakableModel, NULL);
Geometry::registerPluginStream(ID_BREAKABLE,
(StreamRead)readBreakableModel,
(StreamWrite)writeBreakableModel,
(StreamGetSize)getSizeBreakableModel);
}

View File

@ -59,6 +59,11 @@ enum PluginID
ID_ANIMANIMATION = 0x1B,
ID_RIGHTTORENDER = 0x1F,
ID_UVANIMDICT = 0x2B,
ID_NATIVEDATA = 0x510,
ID_EXTRACOLORS = 0x253f2f9,
ID_BREAKABLE = 0x253f2fd
};
extern int Version;

View File

@ -211,3 +211,4 @@ private:
void registerNodeNamePlugin(void);
void registerMeshPlugin(void);
void registerNativeDataPlugin(void);
void registerBreakableModelPlugin(void);

View File

@ -4,7 +4,7 @@ namespace Gl {
struct AttribDesc
{
// arguments to glVertexAttribPointer (should use OpenGL types here)
// Vertex = 0, TexCoord, Normal, Color, Weight, Bone Index
// Vertex = 0, TexCoord, Normal, Color, Weight, Bone Index, Extra Color
uint32 index;
// float = 0, byte, ubyte, short, ushort
int32 type;

View File

@ -80,11 +80,11 @@ PluginBase<T>::copyPlugins(T *t)
template <typename T> void
PluginBase<T>::streamReadPlugins(std::istream &stream)
{
uint32 length;
int32 length;
Rw::ChunkHeaderInfo header;
if(!Rw::FindChunk(stream, Rw::ID_EXTENSION, &length, NULL))
if(!Rw::FindChunk(stream, Rw::ID_EXTENSION, (uint32*)&length, NULL))
return;
while(length){
while(length > 0){
Rw::ReadChunkHeaderInfo(stream, &header);
length -= 12;
for(Plugin *p = this->s_plugins; p; p = p->next)