Worked on the Geometry.

This commit is contained in:
Angelo Papenhoff 2014-12-19 22:58:10 +01:00
parent 37e027b17c
commit c0c8271b03
4 changed files with 121 additions and 109 deletions

View File

@ -1,6 +1,7 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <cassert>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
@ -48,6 +49,26 @@ Frame::addChild(Frame *child)
return this; return this;
} }
Frame*
Frame::removeChild(void)
{
Frame *parent = (Frame*)this->parent;
if(parent->child == this)
parent->child = this->next;
else{
Frame *f;
for(f = parent->child; f; f = f->next)
if(f->next == this)
goto found;
// not found
found:
f->next = f->next->next;
}
this->parent = NULL;
this->next = this->root = NULL;
return this;
}
Frame* Frame*
Frame::forAllChildren(Callback cb, void *data) Frame::forAllChildren(Callback cb, void *data)
{ {
@ -120,8 +141,7 @@ Clump::streamRead(istream &stream)
uint32 length, version; uint32 length, version;
int32 buf[3]; int32 buf[3];
Clump *clump; Clump *clump;
if(!FindChunk(stream, ID_STRUCT, &length, &version)) assert(FindChunk(stream, ID_STRUCT, &length, &version));
return NULL;
clump = new Clump; clump = new Clump;
stream.read((char*)buf, length); stream.read((char*)buf, length);
clump->numAtomics = buf[0]; clump->numAtomics = buf[0];
@ -140,23 +160,19 @@ Clump::streamRead(istream &stream)
// Geometry list // Geometry list
int32 numGeometries = 0; int32 numGeometries = 0;
if(!FindChunk(stream, ID_GEOMETRYLIST, NULL, NULL)) assert(FindChunk(stream, ID_GEOMETRYLIST, NULL, NULL));
return NULL; assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
if(!FindChunk(stream, ID_STRUCT, NULL, NULL))
return NULL;
numGeometries = readInt32(stream); numGeometries = readInt32(stream);
Geometry **geometryList = new Geometry*[numGeometries]; Geometry **geometryList = new Geometry*[numGeometries];
for(int32 i = 0; i < numGeometries; i++){ for(int32 i = 0; i < numGeometries; i++){
if(!FindChunk(stream, ID_GEOMETRY, NULL, NULL)) assert(FindChunk(stream, ID_GEOMETRY, NULL, NULL));
return NULL;
geometryList[i] = Geometry::streamRead(stream); geometryList[i] = Geometry::streamRead(stream);
} }
// Atomics // Atomics
clump->atomicList = new Atomic*[clump->numAtomics]; clump->atomicList = new Atomic*[clump->numAtomics];
for(int32 i = 0; i < clump->numAtomics; i++){ for(int32 i = 0; i < clump->numAtomics; i++){
if(!FindChunk(stream, ID_ATOMIC, NULL, NULL)) assert(FindChunk(stream, ID_ATOMIC, NULL, NULL));
return NULL;
clump->atomicList[i] = Atomic::streamReadClump(stream, clump->atomicList[i] = Atomic::streamReadClump(stream,
frameList, geometryList); frameList, geometryList);
clump->atomicList[i]->clump = clump; clump->atomicList[i]->clump = clump;
@ -166,11 +182,9 @@ Clump::streamRead(istream &stream)
clump->lightList = new Light*[clump->numLights]; clump->lightList = new Light*[clump->numLights];
for(int32 i = 0; i < clump->numLights; i++){ for(int32 i = 0; i < clump->numLights; i++){
int32 frm; int32 frm;
if(!FindChunk(stream, ID_STRUCT, NULL, NULL)) assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
return NULL;
frm = readInt32(stream); frm = readInt32(stream);
if(!FindChunk(stream, ID_LIGHT, NULL, NULL)) assert(FindChunk(stream, ID_LIGHT, NULL, NULL));
return NULL;
clump->lightList[i] = Light::streamRead(stream); clump->lightList[i] = Light::streamRead(stream);
clump->lightList[i]->frame = frameList[frm]; clump->lightList[i]->frame = frameList[frm];
clump->lightList[i]->clump = clump; clump->lightList[i]->clump = clump;
@ -271,10 +285,8 @@ Clump::frameListStreamRead(istream &stream, Frame ***flp, int32 *nf)
{ {
FrameStreamData buf; FrameStreamData buf;
int32 numFrames = 0; int32 numFrames = 0;
if(!FindChunk(stream, ID_FRAMELIST, NULL, NULL)) assert(FindChunk(stream, ID_FRAMELIST, NULL, NULL));
return; assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
if(!FindChunk(stream, ID_STRUCT, NULL, NULL))
return;
numFrames = readInt32(stream); numFrames = readInt32(stream);
Frame **frameList = new Frame*[numFrames]; Frame **frameList = new Frame*[numFrames];
for(int32 i = 0; i < numFrames; i++){ for(int32 i = 0; i < numFrames; i++){
@ -368,8 +380,7 @@ Atomic::streamReadClump(istream &stream,
Frame **frameList, Geometry **geometryList) Frame **frameList, Geometry **geometryList)
{ {
int32 buf[4]; int32 buf[4];
if(!FindChunk(stream, ID_STRUCT, NULL, NULL)) assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
return NULL;
stream.read((char*)buf, 16); stream.read((char*)buf, 16);
Atomic *atomic = new Atomic; Atomic *atomic = new Atomic;
atomic->frame = frameList[buf[0]]; atomic->frame = frameList[buf[0]];
@ -438,8 +449,7 @@ Light*
Light::streamRead(istream &stream) Light::streamRead(istream &stream)
{ {
LightChunkData buf; LightChunkData buf;
if(!FindChunk(stream, ID_STRUCT, NULL, NULL)) assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
return NULL;
Light *light = new Light; Light *light = new Light;
stream.read((char*)&buf, sizeof(LightChunkData)); stream.read((char*)&buf, sizeof(LightChunkData));
light->radius = buf.radius; light->radius = buf.radius;

View File

@ -1,6 +1,7 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <cassert>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
@ -13,35 +14,58 @@ using namespace std;
namespace Rw { namespace Rw {
Geometry::Geometry(void) Geometry::Geometry(int32 numVerts, int32 numTris, uint32 flags)
{ {
geoflags = 0; this->geoflags = flags & 0xFF00FFFF;
numTriangles = 0; this->numTexCoordSets = (flags & 0xFF0000) >> 16;
numVertices = 0; if(this->numTexCoordSets == 0 && (this->geoflags & TEXTURED))
numMorphTargets = 0; this->numTexCoordSets = 1;
numTexCoordSets = 0; this->numTriangles = numTris;
triangles = 0; this->numVertices = numVerts;
colors = 0; this->numMorphTargets = 1;
for(int i = 0; i < 8; i++)
texCoords[i] = 0;
morphTargets = NULL;
constructPlugins();
}
Geometry::Geometry(Geometry *g) this->colors = NULL;
{ for(int32 i = 0; i < this->numTexCoordSets; i++)
// TODO this->texCoords[i] = NULL;
geoflags = g->geoflags; this->triangles = NULL;
numTriangles = g->numTriangles; if(!(this->geoflags & 0xFF000000)){
numVertices = g->numVertices; if(this->geoflags & PRELIT)
numMorphTargets = g->numMorphTargets; this->colors = new uint8[4*this->numVertices];
numTexCoordSets = g->numTexCoordSets; if((this->geoflags & TEXTURED) || (this->geoflags & TEXTURED2))
copyPlugins(g); for(int32 i = 0; i < this->numTexCoordSets; i++)
this->texCoords[i] =
new float32[2*this->numVertices];
this->triangles = new uint16[4*this->numTriangles];
}
this->morphTargets = new MorphTarget[1];
MorphTarget *m = this->morphTargets;
m->vertices = NULL;
m->normals = NULL;
if(!(this->geoflags & 0xFF000000)){
m->vertices = new float32[3*this->numVertices];
if(this->geoflags & NORMALS)
m->normals = new float32[3*this->numVertices];
}
this->numMaterials = 0;
materialList = NULL;
meshHeader = NULL;
this->constructPlugins();
} }
Geometry::~Geometry(void) Geometry::~Geometry(void)
{ {
destructPlugins(); this->destructPlugins();
delete[] this->colors;
for(int32 i = 0; i < this->numTexCoordSets; i++)
delete[] this->texCoords[i];
delete[] this->triangles;
for(int32 i = 0; i < this->numMorphTargets; i++){
MorphTarget *m = &this->morphTargets[i];
delete[] m->vertices;
delete[] m->normals;
}
delete[] this->morphTargets;
} }
struct GeoStreamData struct GeoStreamData
@ -57,63 +81,43 @@ Geometry::streamRead(istream &stream)
{ {
uint32 version; uint32 version;
GeoStreamData buf; GeoStreamData buf;
if(!FindChunk(stream, ID_STRUCT, NULL, &version)) assert(FindChunk(stream, ID_STRUCT, NULL, &version));
return NULL;
Geometry *geo = new Geometry;
stream.read((char*)&buf, sizeof(buf)); stream.read((char*)&buf, sizeof(buf));
geo->geoflags = buf.flags & 0xFF00FFFF; Geometry *geo = new Geometry(buf.numVertices,
geo->numTexCoordSets = (buf.flags & 0xFF0000) >> 16; buf.numTriangles, buf.flags);
if(geo->numTexCoordSets == 0 && (geo->geoflags & TEXTURED)) geo->addMorphTargets(buf.numMorphTargets-1);
geo->numTexCoordSets = 1;
geo->numTriangles = buf.numTriangles;
geo->numVertices = buf.numVertices;
geo->numMorphTargets = buf.numMorphTargets;
// skip surface properties // skip surface properties
if(version < 0x34000) if(version < 0x34000)
stream.seekg(12, ios::cur); stream.seekg(12, ios::cur);
if(!(geo->geoflags & 0xFF000000)){ if(!(geo->geoflags & 0xFF000000)){
if(geo->geoflags & PRELIT){ if(geo->geoflags & PRELIT)
geo->colors = new uint8[4*geo->numVertices];
stream.read((char*)geo->colors, 4*geo->numVertices); stream.read((char*)geo->colors, 4*geo->numVertices);
}
if((geo->geoflags & TEXTURED) || (geo->geoflags & TEXTURED2)) if((geo->geoflags & TEXTURED) || (geo->geoflags & TEXTURED2))
for(int32 i = 0; i < geo->numTexCoordSets; i++){ for(int32 i = 0; i < geo->numTexCoordSets; i++)
geo->texCoords[i] =
new float32[2*geo->numVertices];
stream.read((char*)geo->texCoords[i], stream.read((char*)geo->texCoords[i],
2*geo->numVertices*4); 2*geo->numVertices*4);
}
geo->triangles = new uint16[4*geo->numTriangles];
stream.read((char*)geo->triangles, 4*geo->numTriangles*2); stream.read((char*)geo->triangles, 4*geo->numTriangles*2);
} }
geo->morphTargets = new MorphTarget[geo->numMorphTargets];
for(int32 i = 0; i < geo->numMorphTargets; i++){ for(int32 i = 0; i < geo->numMorphTargets; i++){
MorphTarget *m = &geo->morphTargets[i]; MorphTarget *m = &geo->morphTargets[i];
stream.read((char*)m->boundingSphere, 4*4); stream.read((char*)m->boundingSphere, 4*4);
int32 hasVertices = readInt32(stream); int32 hasVertices = readInt32(stream);
int32 hasNormals = readInt32(stream); int32 hasNormals = readInt32(stream);
if(hasVertices){ if(hasVertices)
m->vertices = new float32[3*geo->numVertices];
stream.read((char*)m->vertices, 3*geo->numVertices*4); stream.read((char*)m->vertices, 3*geo->numVertices*4);
} if(hasNormals)
if(hasNormals){
m->normals = new float32[3*geo->numVertices];
stream.read((char*)m->normals, 3*geo->numVertices*4); stream.read((char*)m->normals, 3*geo->numVertices*4);
}
} }
if(!FindChunk(stream, ID_MATLIST, NULL, NULL)) assert(FindChunk(stream, ID_MATLIST, NULL, NULL));
return geo; assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
if(!FindChunk(stream, ID_STRUCT, NULL, NULL))
return geo;
geo->numMaterials = readInt32(stream); geo->numMaterials = readInt32(stream);
geo->materialList = new Material*[geo->numMaterials]; geo->materialList = new Material*[geo->numMaterials];
stream.seekg(geo->numMaterials*4, ios::cur); // unused (-1) stream.seekg(geo->numMaterials*4, ios::cur); // unused (-1)
for(int32 i = 0; i < geo->numMaterials; i++){ for(int32 i = 0; i < geo->numMaterials; i++){
if(!FindChunk(stream, ID_MATERIAL, NULL, NULL)) assert(FindChunk(stream, ID_MATERIAL, NULL, NULL));
return geo;
geo->materialList[i] = Material::streamRead(stream); geo->materialList[i] = Material::streamRead(stream);
} }
@ -215,6 +219,28 @@ Geometry::streamGetSize(void)
return size; return size;
} }
void
Geometry::addMorphTargets(int32 n)
{
if(n == 0)
return;
MorphTarget *morphTargets = new MorphTarget[this->numMorphTargets+n];
memcpy(morphTargets, this->morphTargets,
this->numMorphTargets*sizeof(MorphTarget));
delete[] this->morphTargets;
this->morphTargets = morphTargets;
for(int32 i = this->numMorphTargets; i < n; i++){
MorphTarget *m = &morphTargets[i];
m->vertices = NULL;
m->normals = NULL;
if(!(this->geoflags & 0xFF000000)){
m->vertices = new float32[3*this->numVertices];
if(this->geoflags & NORMALS)
m->normals = new float32[3*this->numVertices];
}
}
this->numMorphTargets += n;
}
@ -258,8 +284,7 @@ Material::streamRead(istream &stream)
{ {
uint32 length; uint32 length;
MatStreamData buf; MatStreamData buf;
if(!FindChunk(stream, ID_STRUCT, NULL, NULL)) assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
return NULL;
stream.read((char*)&buf, sizeof(buf)); stream.read((char*)&buf, sizeof(buf));
Material *mat = new Material; Material *mat = new Material;
mat->color[0] = buf.color[0]; mat->color[0] = buf.color[0];
@ -271,8 +296,7 @@ Material::streamRead(istream &stream)
mat->surfaceProps[2] = buf.surfaceProps[2]; mat->surfaceProps[2] = buf.surfaceProps[2];
if(buf.textured){ if(buf.textured){
if(!FindChunk(stream, ID_TEXTURE, &length, NULL)) assert(FindChunk(stream, ID_TEXTURE, &length, NULL));
return NULL;
mat->texture = Texture::streamRead(stream); mat->texture = Texture::streamRead(stream);
} }
@ -346,18 +370,15 @@ Texture*
Texture::streamRead(istream &stream) Texture::streamRead(istream &stream)
{ {
uint32 length; uint32 length;
if(!FindChunk(stream, ID_STRUCT, NULL, NULL)) assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
return NULL;
Texture *tex = new Texture; Texture *tex = new Texture;
tex->filterAddressing = readUInt16(stream); tex->filterAddressing = readUInt16(stream);
stream.seekg(2, ios::cur); stream.seekg(2, ios::cur);
if(!FindChunk(stream, ID_STRING, &length, NULL)) assert(FindChunk(stream, ID_STRING, &length, NULL));
return NULL;
stream.read(tex->name, length); stream.read(tex->name, length);
if(!FindChunk(stream, ID_STRING, &length, NULL)) assert(FindChunk(stream, ID_STRING, &length, NULL));
return NULL;
stream.read(tex->mask, length); stream.read(tex->mask, length);
tex->streamReadPlugins(stream); tex->streamReadPlugins(stream);

View File

@ -71,24 +71,6 @@ registerNodeNamePlugin(void)
} }
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 static void
readMesh(istream &stream, Rw::int32, void *object, int32, int32) readMesh(istream &stream, Rw::int32, void *object, int32, int32)
{ {
@ -164,9 +146,7 @@ getSizeMesh(void *object, int32)
void void
registerMeshPlugin(void) registerMeshPlugin(void)
{ {
Rw::Geometry::registerPlugin(0, 0x50E, (Constructor)createMesh, Rw::Geometry::registerPlugin(0, 0x50E, NULL, NULL, NULL);
(Destructor)destroyMesh,
(CopyConstructor)copyMesh);
Rw::Geometry::registerPluginStream(0x50E, (StreamRead)readMesh, Rw::Geometry::registerPluginStream(0x50E, (StreamRead)readMesh,
(StreamWrite)writeMesh, (StreamWrite)writeMesh,
(StreamGetSize)getSizeMesh); (StreamGetSize)getSizeMesh);

5
rw.h
View File

@ -78,12 +78,12 @@ struct Geometry : PluginBase<Geometry>, Object
MeshHeader *meshHeader; MeshHeader *meshHeader;
Geometry(void); Geometry(int32 numVerts, int32 numTris, uint32 flags);
Geometry(Geometry *g);
~Geometry(void); ~Geometry(void);
static Geometry *streamRead(std::istream &stream); static Geometry *streamRead(std::istream &stream);
bool streamWrite(std::ostream &stream); bool streamWrite(std::ostream &stream);
uint32 streamGetSize(void); uint32 streamGetSize(void);
void addMorphTargets(int32 n);
enum Flags enum Flags
{ {
@ -117,6 +117,7 @@ struct Frame : PluginBase<Frame>, Object
Frame(Frame *f); Frame(Frame *f);
~Frame(void); ~Frame(void);
Frame *addChild(Frame *f); Frame *addChild(Frame *f);
Frame *removeChild(void);
Frame *forAllChildren(Callback cb, void *data); Frame *forAllChildren(Callback cb, void *data);
int32 count(void); int32 count(void);
}; };