Implemented Mesh and Node Name plugins.

This commit is contained in:
Angelo Papenhoff 2014-12-19 16:24:29 +01:00
parent 02db884c0c
commit 37e027b17c
7 changed files with 220 additions and 24 deletions

View File

@ -13,18 +13,6 @@ using namespace std;
namespace Rw {
static int32
findFrame(Frame *f, Frame **frameList, int32 numFrames)
{
int frm;
for(frm = 0; frm < numFrames; frm++)
if(frameList[frm] == f)
goto foundfrm;
return -1;
foundfrm:
return frm;
}
Frame::Frame(void)
{
this->child = NULL;
@ -224,7 +212,7 @@ Clump::streamWrite(ostream &stream)
for(int32 i = 0; i < this->numLights; i++){
Light *l = this->lightList[i];
int frm = findFrame(l->frame, flist, numFrames);
int frm = findPointer((void*)l->frame, (void**)flist,numFrames);
if(frm < 0)
return false;
WriteChunkHeader(stream, ID_STRUCT, 4);
@ -347,7 +335,7 @@ Clump::frameListStreamWrite(ostream &stream, Frame **frameList, int32 numFrames)
buf.pos[0] = f->matrix[12];
buf.pos[1] = f->matrix[13];
buf.pos[2] = f->matrix[14];
buf.parent = findFrame(f, frameList, numFrames);
buf.parent = findPointer((void*)f, (void**)frameList,numFrames);
buf.matflag = f->matflag;
stream.write((char*)&buf, sizeof(buf));
}
@ -399,7 +387,7 @@ Atomic::streamWriteClump(ostream &stream, Frame **frameList, int32 numFrames)
return false;
WriteChunkHeader(stream, ID_ATOMIC, this->streamGetSize());
WriteChunkHeader(stream, ID_STRUCT, 16);
buf[0] = findFrame(this->frame, frameList, numFrames);
buf[0] = findPointer((void*)this->frame, (void**)frameList, numFrames);
// TODO
for(buf[1] = 0; buf[1] < c->numAtomics; buf[1]++)

View File

@ -74,10 +74,9 @@ main(int argc, char *argv[])
// Rw::Version = 0x31000;
// Rw::Build = 0;
// int Xoff = Rw::Clump::registerPlugin(8, 0x123, ctorX, dtorX, cctorX);
// Xoff = Rw::Clump::registerPluginStream(0x123, readX, writeX, getSizeX);
registerNodeNamePlugin();
registerMeshPlugin();
Rw::Clump *c;
// X *x;
ifstream in(argv[1], ios::binary);
Rw::FindChunk(in, Rw::ID_CLUMP, NULL, NULL);

175
plugins.cpp Normal file
View File

@ -0,0 +1,175 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <fstream>
#include "rwbase.h"
#include "rwplugin.h"
#include "rw.h"
using namespace std;
using namespace Rw;
static void*
createNodeName(void *object, int32 offset, int32)
{
char *name = PLUGINOFFSET(char, object, offset);
name[0] = '\0';
return object;
}
static void*
copyNodeName(void *dst, void *src, int32 offset, int32)
{
char *dstname = PLUGINOFFSET(char, dst, offset);
char *srcname = PLUGINOFFSET(char, src, offset);
strncpy(dstname, srcname, 17);
return dst;
}
static void*
destroyNodeName(void *object, int32, int32)
{
return object;
}
static void
readNodeName(istream &stream, Rw::int32 len, void *object, int32 offset, int32)
{
char *name = PLUGINOFFSET(char, object, offset);
stream.read(name, len);
name[len] = '\0';
}
static void
writeNodeName(ostream &stream, Rw::int32 len, void *object, int32 offset, int32)
{
char *name = PLUGINOFFSET(char, object, offset);
stream.write(name, len);
}
static int32
getSizeNodeName(void *object, int32 offset)
{
char *name = PLUGINOFFSET(char, object, offset);
int32 len = strlen(name);
return len > 0 ? len : -1;
}
void
registerNodeNamePlugin(void)
{
Rw::Frame::registerPlugin(18, 0x253f2fe, (Constructor)createNodeName,
(Destructor)destroyNodeName,
(CopyConstructor)copyNodeName);
Rw::Frame::registerPluginStream(0x253f2fe, (StreamRead)readNodeName,
(StreamWrite)writeNodeName,
(StreamGetSize)getSizeNodeName);
}
static void*
createMesh(void *object, int, int)
{
return object;
}
static void*
copyMesh(void *dst, void *src, int, int)
{
return dst;
}
static void*
destroyMesh(void *object, int, int)
{
return object;
}
static void
readMesh(istream &stream, Rw::int32, void *object, int32, int32)
{
Geometry *geo = (Geometry*)object;
uint32 buf[3];
stream.read((char*)buf, 12);
geo->meshHeader = new MeshHeader;
geo->meshHeader->flags = buf[0];
geo->meshHeader->numMeshes = buf[1];
geo->meshHeader->totalIndices = buf[2];
geo->meshHeader->mesh = new Mesh[geo->meshHeader->numMeshes];
Mesh *mesh = geo->meshHeader->mesh;
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
stream.read((char*)buf, 8);
mesh->numIndices = buf[0];
mesh->material = geo->materialList[buf[1]];
mesh->indices = NULL;
if(geo->geoflags & Geometry::NATIVE)
// TODO: compressed indices in OpenGL
;
else{
mesh->indices = new uint16[mesh->numIndices];
for(uint32 j = 0; j < mesh->numIndices; j++)
mesh->indices[j] = readUInt32(stream);
}
mesh++;
}
}
static void
writeMesh(ostream &stream, Rw::int32, void *object, int32, int32)
{
Geometry *geo = (Geometry*)object;
uint32 buf[3];
buf[0] = geo->meshHeader->flags;
buf[1] = geo->meshHeader->numMeshes;
buf[2] = geo->meshHeader->totalIndices;
stream.write((char*)buf, 12);
Mesh *mesh = geo->meshHeader->mesh;
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
buf[0] = mesh->numIndices;
buf[1] = findPointer((void*)mesh->material,
(void**)geo->materialList,
geo->numMaterials);
stream.write((char*)buf, 8);
if(geo->geoflags & Geometry::NATIVE)
// TODO: compressed indices in OpenGL
;
else
for(uint32 j = 0; j < mesh->numIndices; j++)
writeUInt32(mesh->indices[j], stream);
mesh++;
}
}
static int32
getSizeMesh(void *object, int32)
{
Geometry *geo = (Geometry*)object;
if(geo->meshHeader == NULL)
return -1;
int32 size = 12 + geo->meshHeader->numMeshes*8;
if(geo->geoflags & Geometry::NATIVE)
// TODO: compressed indices in OpenGL
;
else{
size += geo->meshHeader->totalIndices*4;
}
return size;
}
void
registerMeshPlugin(void)
{
Rw::Geometry::registerPlugin(0, 0x50E, (Constructor)createMesh,
(Destructor)destroyMesh,
(CopyConstructor)copyMesh);
Rw::Geometry::registerPluginStream(0x50E, (StreamRead)readMesh,
(StreamWrite)writeMesh,
(StreamGetSize)getSizeMesh);
}

21
rw.h
View File

@ -36,6 +36,22 @@ struct Material : PluginBase<Material>
uint32 streamGetSize(void);
};
struct Mesh
{
uint16 *indices;
uint32 numIndices;
Material *material;
};
struct MeshHeader
{
uint32 flags;
uint16 numMeshes;
// RW has uint16 serialNum here
uint32 totalIndices;
Mesh *mesh; // RW has a byte offset here
};
struct MorphTarget
{
float32 boundingSphere[4];
@ -60,6 +76,8 @@ struct Geometry : PluginBase<Geometry>, Object
int32 numMaterials;
Material **materialList;
MeshHeader *meshHeader;
Geometry(void);
Geometry(Geometry *g);
~Geometry(void);
@ -159,3 +177,6 @@ private:
};
}
void registerNodeNamePlugin(void);
void registerMeshPlugin(void);

View File

@ -160,4 +160,16 @@ FindChunk(istream &s, uint32 type, uint32 *length, uint32 *version)
return false;
}
int32
findPointer(void *p, void **list, int32 num)
{
int i;
for(i = 0; i < num; i++)
if(list[i] == p)
goto found;
return -1;
found:
return i;
}
}

View File

@ -97,4 +97,5 @@ bool WriteChunkHeader(std::ostream &s, int32 type, int32 size);
bool ReadChunkHeaderInfo(std::istream &s, ChunkHeaderInfo *header);
bool FindChunk(std::istream &s, uint32 type, uint32 *length, uint32 *version);
int32 findPointer(void *p, void **list, int32 num);
}

View File

@ -3,12 +3,12 @@ namespace Rw {
#define PLUGINOFFSET(type, base, offset) \
((type*)((char*)(base) + (offset)))
typedef void *(*Constructor)(void *object, int offset, int size);
typedef void *(*Destructor)(void *object, int offset, int size);
typedef void *(*CopyConstructor)(void *dst, void *src, int offset, int size);
typedef void (*StreamRead)(std::istream &stream, int length, void *object, int offset, int size);
typedef void (*StreamWrite)(std::ostream &stream, int length, void *object, int offset, int size);
typedef int32 (*StreamGetSize)(void *object, int offset, int size);
typedef void *(*Constructor)(void *object, int32 offset, int32 size);
typedef void *(*Destructor)(void *object, int32 offset, int32 size);
typedef void *(*CopyConstructor)(void *dst, void *src, int32 offset, int32 size);
typedef void (*StreamRead)(std::istream &stream, int32 length, void *object, int32 offset, int32 size);
typedef void (*StreamWrite)(std::ostream &stream, int32 length, void *object, int32 offset, int32 size);
typedef int32 (*StreamGetSize)(void *object, int32 offset, int32 size);
struct Plugin
{