mirror of https://github.com/aap/librw.git
Implemented Mesh and Node Name plugins.
This commit is contained in:
parent
02db884c0c
commit
37e027b17c
18
clump.cpp
18
clump.cpp
|
@ -13,18 +13,6 @@ using namespace std;
|
||||||
|
|
||||||
namespace Rw {
|
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)
|
Frame::Frame(void)
|
||||||
{
|
{
|
||||||
this->child = NULL;
|
this->child = NULL;
|
||||||
|
@ -224,7 +212,7 @@ Clump::streamWrite(ostream &stream)
|
||||||
|
|
||||||
for(int32 i = 0; i < this->numLights; i++){
|
for(int32 i = 0; i < this->numLights; i++){
|
||||||
Light *l = this->lightList[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)
|
if(frm < 0)
|
||||||
return false;
|
return false;
|
||||||
WriteChunkHeader(stream, ID_STRUCT, 4);
|
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[0] = f->matrix[12];
|
||||||
buf.pos[1] = f->matrix[13];
|
buf.pos[1] = f->matrix[13];
|
||||||
buf.pos[2] = f->matrix[14];
|
buf.pos[2] = f->matrix[14];
|
||||||
buf.parent = findFrame(f, frameList, numFrames);
|
buf.parent = findPointer((void*)f, (void**)frameList,numFrames);
|
||||||
buf.matflag = f->matflag;
|
buf.matflag = f->matflag;
|
||||||
stream.write((char*)&buf, sizeof(buf));
|
stream.write((char*)&buf, sizeof(buf));
|
||||||
}
|
}
|
||||||
|
@ -399,7 +387,7 @@ Atomic::streamWriteClump(ostream &stream, Frame **frameList, int32 numFrames)
|
||||||
return false;
|
return false;
|
||||||
WriteChunkHeader(stream, ID_ATOMIC, this->streamGetSize());
|
WriteChunkHeader(stream, ID_ATOMIC, this->streamGetSize());
|
||||||
WriteChunkHeader(stream, ID_STRUCT, 16);
|
WriteChunkHeader(stream, ID_STRUCT, 16);
|
||||||
buf[0] = findFrame(this->frame, frameList, numFrames);
|
buf[0] = findPointer((void*)this->frame, (void**)frameList, numFrames);
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
for(buf[1] = 0; buf[1] < c->numAtomics; buf[1]++)
|
for(buf[1] = 0; buf[1] < c->numAtomics; buf[1]++)
|
||||||
|
|
5
main.cpp
5
main.cpp
|
@ -74,10 +74,9 @@ main(int argc, char *argv[])
|
||||||
// Rw::Version = 0x31000;
|
// Rw::Version = 0x31000;
|
||||||
// Rw::Build = 0;
|
// Rw::Build = 0;
|
||||||
|
|
||||||
// int Xoff = Rw::Clump::registerPlugin(8, 0x123, ctorX, dtorX, cctorX);
|
registerNodeNamePlugin();
|
||||||
// Xoff = Rw::Clump::registerPluginStream(0x123, readX, writeX, getSizeX);
|
registerMeshPlugin();
|
||||||
Rw::Clump *c;
|
Rw::Clump *c;
|
||||||
// X *x;
|
|
||||||
|
|
||||||
ifstream in(argv[1], ios::binary);
|
ifstream in(argv[1], ios::binary);
|
||||||
Rw::FindChunk(in, Rw::ID_CLUMP, NULL, NULL);
|
Rw::FindChunk(in, Rw::ID_CLUMP, NULL, NULL);
|
||||||
|
|
|
@ -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
21
rw.h
|
@ -36,6 +36,22 @@ struct Material : PluginBase<Material>
|
||||||
uint32 streamGetSize(void);
|
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
|
struct MorphTarget
|
||||||
{
|
{
|
||||||
float32 boundingSphere[4];
|
float32 boundingSphere[4];
|
||||||
|
@ -60,6 +76,8 @@ struct Geometry : PluginBase<Geometry>, Object
|
||||||
int32 numMaterials;
|
int32 numMaterials;
|
||||||
Material **materialList;
|
Material **materialList;
|
||||||
|
|
||||||
|
MeshHeader *meshHeader;
|
||||||
|
|
||||||
Geometry(void);
|
Geometry(void);
|
||||||
Geometry(Geometry *g);
|
Geometry(Geometry *g);
|
||||||
~Geometry(void);
|
~Geometry(void);
|
||||||
|
@ -159,3 +177,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void registerNodeNamePlugin(void);
|
||||||
|
void registerMeshPlugin(void);
|
||||||
|
|
12
rwbase.cpp
12
rwbase.cpp
|
@ -160,4 +160,16 @@ FindChunk(istream &s, uint32 type, uint32 *length, uint32 *version)
|
||||||
return false;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
1
rwbase.h
1
rwbase.h
|
@ -97,4 +97,5 @@ bool WriteChunkHeader(std::ostream &s, int32 type, int32 size);
|
||||||
bool ReadChunkHeaderInfo(std::istream &s, ChunkHeaderInfo *header);
|
bool ReadChunkHeaderInfo(std::istream &s, ChunkHeaderInfo *header);
|
||||||
bool FindChunk(std::istream &s, uint32 type, uint32 *length, uint32 *version);
|
bool FindChunk(std::istream &s, uint32 type, uint32 *length, uint32 *version);
|
||||||
|
|
||||||
|
int32 findPointer(void *p, void **list, int32 num);
|
||||||
}
|
}
|
||||||
|
|
12
rwplugin.h
12
rwplugin.h
|
@ -3,12 +3,12 @@ namespace Rw {
|
||||||
#define PLUGINOFFSET(type, base, offset) \
|
#define PLUGINOFFSET(type, base, offset) \
|
||||||
((type*)((char*)(base) + (offset)))
|
((type*)((char*)(base) + (offset)))
|
||||||
|
|
||||||
typedef void *(*Constructor)(void *object, int offset, int size);
|
typedef void *(*Constructor)(void *object, int32 offset, int32 size);
|
||||||
typedef void *(*Destructor)(void *object, int offset, int size);
|
typedef void *(*Destructor)(void *object, int32 offset, int32 size);
|
||||||
typedef void *(*CopyConstructor)(void *dst, void *src, int offset, int size);
|
typedef void *(*CopyConstructor)(void *dst, void *src, int32 offset, int32 size);
|
||||||
typedef void (*StreamRead)(std::istream &stream, int length, void *object, int offset, int size);
|
typedef void (*StreamRead)(std::istream &stream, int32 length, void *object, int32 offset, int32 size);
|
||||||
typedef void (*StreamWrite)(std::ostream &stream, int length, void *object, int offset, int size);
|
typedef void (*StreamWrite)(std::ostream &stream, int32 length, void *object, int32 offset, int32 size);
|
||||||
typedef int32 (*StreamGetSize)(void *object, int offset, int size);
|
typedef int32 (*StreamGetSize)(void *object, int32 offset, int32 size);
|
||||||
|
|
||||||
struct Plugin
|
struct Plugin
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue