mirror of
https://github.com/aap/librw.git
synced 2024-11-25 05:05:42 +00:00
Implemented Breakable model and fixed bug in Extension stream read.
This commit is contained in:
parent
5842f6221b
commit
7b4dd3a5ac
@ -17,6 +17,7 @@ main(int argc, char *argv[])
|
||||
// Rw::Build = 0;
|
||||
|
||||
registerNodeNamePlugin();
|
||||
registerBreakableModelPlugin();
|
||||
registerNativeDataPlugin();
|
||||
registerMeshPlugin();
|
||||
Rw::Clump *c;
|
||||
|
14
src/ogl.cpp
14
src/ogl.cpp
@ -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);
|
||||
|
115
src/plugins.cpp
115
src/plugins.cpp
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -211,3 +211,4 @@ private:
|
||||
void registerNodeNamePlugin(void);
|
||||
void registerMeshPlugin(void);
|
||||
void registerNativeDataPlugin(void);
|
||||
void registerBreakableModelPlugin(void);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user