implemented cameras for streaming

This commit is contained in:
aap 2016-01-13 08:58:15 +01:00
parent 02c809625a
commit da0417571d
7 changed files with 342 additions and 144 deletions

View File

@ -2,6 +2,7 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <cassert> #include <cassert>
#include <cmath>
#include <new> #include <new>
@ -23,7 +24,8 @@ Frame*
Frame::create(void) Frame::create(void)
{ {
Frame *f = (Frame*)malloc(PluginBase::s_size); Frame *f = (Frame*)malloc(PluginBase::s_size);
f->object.init(0, 0); assert(f != NULL);
f->object.init(Frame::ID, 0);
f->objectList.init(); f->objectList.init();
f->child = NULL; f->child = NULL;
f->next = NULL; f->next = NULL;
@ -56,13 +58,13 @@ Frame::destroy(void)
Frame *child; Frame *child;
if(parent){ if(parent){
// remove from child list // remove from child list
child = parent->child; child = parent->child;
if(child == this) if(child == this)
parent->child = this->next; parent->child = this->next;
else{ else{
for(child = child->next; child != this; child = child->next) for(child = child->next; child != this; child = child->next)
; ;
child->next = this->next; child->next = this->next;
} }
this->object.parent = NULL; this->object.parent = NULL;
// Doesn't seem to make much sense, blame criterion. // Doesn't seem to make much sense, blame criterion.
@ -77,10 +79,10 @@ void
Frame::destroyHierarchy(void) Frame::destroyHierarchy(void)
{ {
Frame *next; Frame *next;
for(Frame *child = this->child; child; child = next){ for(Frame *child = this->child; child; child = next){
next = child->next; next = child->next;
child->destroyHierarchy(); child->destroyHierarchy();
} }
this->destructPlugins(); this->destructPlugins();
free(this); free(this);
} }
@ -104,7 +106,7 @@ Frame::addChild(Frame *child)
Frame* Frame*
Frame::removeChild(void) Frame::removeChild(void)
{ {
Frame *parent = (Frame*)this->object.parent; Frame *parent = this->getParent();
if(parent->child == this) if(parent->child == this)
parent->child = this->next; parent->child = this->next;
else{ else{
@ -150,7 +152,7 @@ Frame::updateLTM(void)
{ {
if(!this->dirty) if(!this->dirty)
return; return;
Frame *parent = (Frame*)this->object.parent; Frame *parent = this->getParent();
if(parent){ if(parent){
parent->updateLTM(); parent->updateLTM();
matrixMult(this->ltm, parent->ltm, this->matrix); matrixMult(this->ltm, parent->ltm, this->matrix);
@ -179,8 +181,8 @@ Frame::setDirty(void)
void void
Frame::setHierarchyRoot(Frame *root) Frame::setHierarchyRoot(Frame *root)
{ {
this->root = root; this->root = root;
for(Frame *child = this->child; child; child = child->next) for(Frame *child = this->child; child; child = child->next)
child->setHierarchyRoot(root); child->setHierarchyRoot(root);
} }
@ -196,7 +198,7 @@ Frame::cloneAndLink(Frame *clonedroot)
frame->root = clonedroot; frame->root = clonedroot;
this->root = frame; // Remember cloned frame this->root = frame; // Remember cloned frame
for(Frame *child = this->child; child; child = child->next){ for(Frame *child = this->child; child; child = child->next){
Frame *clonedchild = child->cloneAndLink(clonedroot); Frame *clonedchild = child->cloneAndLink(clonedroot);
clonedchild->next = frame->child; clonedchild->next = frame->child;
frame->child = clonedchild; frame->child = clonedchild;
clonedchild->object.parent = frame; clonedchild->object.parent = frame;
@ -240,9 +242,11 @@ Clump*
Clump::create(void) Clump::create(void)
{ {
Clump *clump = (Clump*)malloc(PluginBase::s_size); Clump *clump = (Clump*)malloc(PluginBase::s_size);
clump->object.init(2, 0); assert(clump != NULL);
clump->object.init(Clump::ID, 0);
clump->atomics.init(); clump->atomics.init();
clump->lights.init(); clump->lights.init();
clump->cameras.init();
clump->constructPlugins(); clump->constructPlugins();
return clump; return clump;
} }
@ -273,6 +277,8 @@ Clump::destroy(void)
Atomic::fromClump(lnk)->destroy(); Atomic::fromClump(lnk)->destroy();
FORLIST(lnk, this->lights) FORLIST(lnk, this->lights)
Light::fromClump(lnk)->destroy(); Light::fromClump(lnk)->destroy();
FORLIST(lnk, this->cameras)
Camera::fromClump(lnk)->destroy();
if(f = this->getFrame()) if(f = this->getFrame())
f->destroyHierarchy(); f->destroyHierarchy();
free(this); free(this);
@ -296,6 +302,15 @@ Clump::countLights(void)
return n; return n;
} }
int32
Clump::countCameras(void)
{
int32 n = 0;
FORLIST(l, this->cameras)
n++;
return n;
}
Clump* Clump*
Clump::streamRead(Stream *stream) Clump::streamRead(Stream *stream)
{ {
@ -307,15 +322,17 @@ Clump::streamRead(Stream *stream)
stream->read(buf, length); stream->read(buf, length);
int32 numAtomics = buf[0]; int32 numAtomics = buf[0];
int32 numLights = 0; int32 numLights = 0;
if(version > 0x33000) int32 numCameras = 0;
if(version > 0x33000){
numLights = buf[1]; numLights = buf[1];
// ignore cameras numCameras = buf[2];
}
// Frame list // Frame list
Frame **frameList; Frame **frameList;
int32 numFrames; int32 numFrames;
clump->frameListStreamRead(stream, &frameList, &numFrames); clump->frameListStreamRead(stream, &frameList, &numFrames);
clump->object.parent = (void*)frameList[0]; clump->setFrame(frameList[0]);
Geometry **geometryList = 0; Geometry **geometryList = 0;
if(version >= 0x30400){ if(version >= 0x30400){
@ -350,6 +367,17 @@ Clump::streamRead(Stream *stream)
clump->addLight(l); clump->addLight(l);
} }
// Cameras
for(int32 i = 0; i < numCameras; i++){
int32 frm;
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
frm = stream->readI32();
assert(findChunk(stream, ID_CAMERA, NULL, NULL));
Camera *cam = Camera::streamRead(stream);
cam->setFrame(frameList[frm]);
clump->addCamera(cam);
}
delete[] frameList; delete[] frameList;
clump->streamReadPlugins(stream); clump->streamReadPlugins(stream);
@ -368,9 +396,9 @@ Clump::streamWrite(Stream *stream)
writeChunkHeader(stream, ID_STRUCT, size); writeChunkHeader(stream, ID_STRUCT, size);
stream->write(buf, size); stream->write(buf, size);
int32 numFrames = ((Frame*)this->object.parent)->count(); int32 numFrames = this->getFrame()->count();
Frame **flist = new Frame*[numFrames]; Frame **flist = new Frame*[numFrames];
makeFrameList((Frame*)this->object.parent, flist); makeFrameList(this->getFrame(), flist);
this->frameListStreamWrite(stream, flist, numFrames); this->frameListStreamWrite(stream, flist, numFrames);
@ -390,7 +418,7 @@ Clump::streamWrite(Stream *stream)
FORLIST(lnk, this->lights){ FORLIST(lnk, this->lights){
Light *l = Light::fromClump(lnk); Light *l = Light::fromClump(lnk);
int frm = findPointer((void*)l->object.parent, (void**)flist, numFrames); int frm = findPointer(l->getFrame(), (void**)flist, numFrames);
if(frm < 0) if(frm < 0)
return false; return false;
writeChunkHeader(stream, ID_STRUCT, 4); writeChunkHeader(stream, ID_STRUCT, 4);
@ -398,6 +426,16 @@ Clump::streamWrite(Stream *stream)
l->streamWrite(stream); l->streamWrite(stream);
} }
FORLIST(lnk, this->cameras){
Camera *c = Camera::fromClump(lnk);
int frm = findPointer(c->getFrame(), (void**)flist, numFrames);
if(frm < 0)
return false;
writeChunkHeader(stream, ID_STRUCT, 4);
stream->writeI32(frm);
c->streamWrite(stream);
}
delete[] flist; delete[] flist;
this->streamWritePlugins(stream); this->streamWritePlugins(stream);
@ -421,26 +459,30 @@ Clump::streamGetSize(void)
if(version > 0x33000) if(version > 0x33000)
size += 8; // numLights, numCameras size += 8; // numLights, numCameras
// frame list // Frame list
int32 numFrames = ((Frame*)this->object.parent)->count(); int32 numFrames = this->getFrame()->count();
size += 12 + 12 + 4 + numFrames*(sizeof(FrameStreamData)+12); size += 12 + 12 + 4 + numFrames*(sizeof(FrameStreamData)+12);
sizeCB((Frame*)this->object.parent, (void*)&size); sizeCB(this->getFrame(), (void*)&size);
if(rw::version >= 0x30400){ if(rw::version >= 0x30400){
// geometry list // Geometry list
size += 12 + 12 + 4; size += 12 + 12 + 4;
FORLIST(lnk, this->atomics) FORLIST(lnk, this->atomics)
size += 12 + Atomic::fromClump(lnk)->geometry->streamGetSize(); size += 12 + Atomic::fromClump(lnk)->geometry->streamGetSize();
} }
// atomics // Atomics
FORLIST(lnk, this->atomics) FORLIST(lnk, this->atomics)
size += 12 + Atomic::fromClump(lnk)->streamGetSize(); size += 12 + Atomic::fromClump(lnk)->streamGetSize();
// light // Lights
FORLIST(lnk, this->lights) FORLIST(lnk, this->lights)
size += 16 + 12 + Light::fromClump(lnk)->streamGetSize(); size += 16 + 12 + Light::fromClump(lnk)->streamGetSize();
// Cameras
FORLIST(lnk, this->cameras)
size += 16 + 12 + Camera::fromClump(lnk)->streamGetSize();
size += 12 + this->streamGetPluginSize(); size += 12 + this->streamGetPluginSize();
return size; return size;
} }
@ -513,7 +555,7 @@ Clump::frameListStreamWrite(Stream *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 = findPointer((void*)f->object.parent, (void**)frameList, buf.parent = findPointer(f->getParent(), (void**)frameList,
numFrames); numFrames);
buf.matflag = f->matflag; buf.matflag = f->matflag;
stream->write(&buf, sizeof(buf)); stream->write(&buf, sizeof(buf));
@ -530,12 +572,13 @@ Atomic*
Atomic::create(void) Atomic::create(void)
{ {
Atomic *atomic = (Atomic*)malloc(PluginBase::s_size); Atomic *atomic = (Atomic*)malloc(PluginBase::s_size);
atomic->object.init(1, 0); assert(atomic != NULL);
atomic->object.init(Atomic::ID, 0);
atomic->geometry = NULL; atomic->geometry = NULL;
atomic->pipeline = NULL; atomic->pipeline = NULL;
atomic->constructPlugins(); atomic->constructPlugins();
return atomic; return atomic;
} }
Atomic* Atomic*
Atomic::clone() Atomic::clone()
@ -596,7 +639,7 @@ Atomic::streamWriteClump(Stream *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, rw::version < 0x30400 ? 12 : 16); writeChunkHeader(stream, ID_STRUCT, rw::version < 0x30400 ? 12 : 16);
buf[0] = findPointer((void*)this->object.parent, (void**)frameList, numFrames); buf[0] = findPointer(this->getFrame(), (void**)frameList, numFrames);
if(version < 0x30400){ if(version < 0x30400){
stream->write(buf, sizeof(int[3])); stream->write(buf, sizeof(int[3]));
@ -702,15 +745,15 @@ Light*
Light::create(int32 type) Light::create(int32 type)
{ {
Light *light = (Light*)malloc(PluginBase::s_size); Light *light = (Light*)malloc(PluginBase::s_size);
light->object.init(3, type); assert(light != NULL);
light->object.init(Light::ID, type);
light->radius = 0.0f; light->radius = 0.0f;
light->color[0] = 1.0f; light->red = 1.0f;
light->color[1] = 1.0f; light->green = 1.0f;
light->color[2] = 1.0f; light->blue = 1.0f;
light->color[3] = 1.0f;
light->minusCosAngle = 1.0f; light->minusCosAngle = 1.0f;
light->object.privateFlags = 1; light->object.privateFlags = 1;
light->object.flags = 1 | 2; light->object.flags = LIGHTATOMICS | LIGHTWORLD;
light->inClump.init(); light->inClump.init();
light->constructPlugins(); light->constructPlugins();
return light; return light;
@ -723,6 +766,27 @@ Light::destroy(void)
free(this); free(this);
} }
void
Light::setAngle(float32 angle)
{
this->minusCosAngle = -cos(angle);
}
float32
Light::getAngle(void)
{
return acos(-this->minusCosAngle);
}
void
Light::setColor(float32 r, float32 g, float32 b)
{
this->red = r;
this->green = g;
this->blue = b;
this->object.privateFlags = r == g && r == b;
}
struct LightChunkData struct LightChunkData
{ {
float32 radius; float32 radius;
@ -735,18 +799,20 @@ struct LightChunkData
Light* Light*
Light::streamRead(Stream *stream) Light::streamRead(Stream *stream)
{ {
uint32 version;
LightChunkData buf; LightChunkData buf;
assert(findChunk(stream, ID_STRUCT, NULL, NULL)); assert(findChunk(stream, ID_STRUCT, NULL, &version));
stream->read(&buf, sizeof(LightChunkData)); stream->read(&buf, sizeof(LightChunkData));
Light *light = Light::create(buf.type); Light *light = Light::create(buf.type);
light->radius = buf.radius; light->radius = buf.radius;
light->color[0] = buf.red; light->setColor(buf.red, buf.green, buf.blue);
light->color[1] = buf.green; float32 a = buf.minusCosAngle;
light->color[2] = buf.blue; if(version >= 0x30300)
light->color[3] = 1.0f; light->minusCosAngle = a;
light->minusCosAngle = buf.minusCosAngle; else
// tan -> -cos
light->minusCosAngle = -1.0f/sqrt(a*a+1.0f);
light->object.flags = (uint8)buf.flags; light->object.flags = (uint8)buf.flags;
light->streamReadPlugins(stream); light->streamReadPlugins(stream);
return light; return light;
} }
@ -758,10 +824,13 @@ Light::streamWrite(Stream *stream)
writeChunkHeader(stream, ID_LIGHT, this->streamGetSize()); writeChunkHeader(stream, ID_LIGHT, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, sizeof(LightChunkData)); writeChunkHeader(stream, ID_STRUCT, sizeof(LightChunkData));
buf.radius = this->radius; buf.radius = this->radius;
buf.red = this->color[0]; buf.red = this->red;
buf.green = this->color[1]; buf.green = this->green;
buf.blue = this->color[2]; buf.blue = this->blue;
buf.minusCosAngle = this->minusCosAngle; if(version >= 0x30300)
buf.minusCosAngle = this->minusCosAngle;
else
buf.minusCosAngle = tan(acos(-this->minusCosAngle));
buf.flags = this->object.flags; buf.flags = this->object.flags;
buf.type = this->object.subType; buf.type = this->object.subType;
stream->write(&buf, sizeof(LightChunkData)); stream->write(&buf, sizeof(LightChunkData));
@ -776,4 +845,83 @@ Light::streamGetSize(void)
return 12 + sizeof(LightChunkData) + 12 + this->streamGetPluginSize(); return 12 + sizeof(LightChunkData) + 12 + this->streamGetPluginSize();
} }
//
// Camera
//
Camera*
Camera::create(void)
{
Camera *cam = (Camera*)malloc(PluginBase::s_size);
cam->object.init(Camera::ID, 0);
cam->constructPlugins();
return cam;
}
Camera*
Camera::clone(void)
{
Camera *cam = Camera::create();
cam->object.copy(&this->object);
cam->copyPlugins(this);
return cam;
}
void
Camera::destroy(void)
{
this->destructPlugins();
free(this);
}
struct CameraChunkData
{
V2d viewWindow;
V2d viewOffset;
float32 nearClip, farClip;
float32 fogPlane;
int32 projection;
};
Camera*
Camera::streamRead(Stream *stream)
{
CameraChunkData buf;
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
stream->read(&buf, sizeof(CameraChunkData));
Camera *cam = Camera::create();
cam->viewWindow = buf.viewWindow;
cam->viewOffset = buf.viewOffset;
cam->nearClip = buf.nearClip;
cam->farClip = buf.farClip;
cam->fogPlane = buf.fogPlane;
cam->projection = buf.projection;
cam->streamReadPlugins(stream);
return cam;
}
bool
Camera::streamWrite(Stream *stream)
{
CameraChunkData buf;
writeChunkHeader(stream, ID_CAMERA, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, sizeof(CameraChunkData));
buf.viewWindow = this->viewWindow;
buf.viewOffset = this->viewOffset;
buf.nearClip = this->nearClip;
buf.farClip = this->farClip;
buf.fogPlane = this->fogPlane;
buf.projection = this->projection;
stream->write(&buf, sizeof(CameraChunkData));
this->streamWritePlugins(stream);
return true;
}
uint32
Camera::streamGetSize(void)
{
return 12 + sizeof(CameraChunkData) + 12 + this->streamGetPluginSize();
}
} }

View File

@ -19,7 +19,8 @@ Geometry*
Geometry::create(int32 numVerts, int32 numTris, uint32 flags) Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
{ {
Geometry *geo = (Geometry*)malloc(PluginBase::s_size); Geometry *geo = (Geometry*)malloc(PluginBase::s_size);
geo->object.init(8, 0); assert(geo != NULL);
geo->object.init(Geometry::ID, 0);
geo->geoflags = flags & 0xFF00FFFF; geo->geoflags = flags & 0xFF00FFFF;
geo->numTexCoordSets = (flags & 0xFF0000) >> 16; geo->numTexCoordSets = (flags & 0xFF0000) >> 16;
if(geo->numTexCoordSets == 0) if(geo->numTexCoordSets == 0)
@ -70,7 +71,7 @@ void
Geometry::destroy(void) Geometry::destroy(void)
{ {
this->refCount--; this->refCount--;
if(this->refCount == 0){ if(this->refCount <= 0){
this->destructPlugins(); this->destructPlugins();
delete[] this->colors; delete[] this->colors;
for(int32 i = 0; i < this->numTexCoordSets; i++) for(int32 i = 0; i < this->numTexCoordSets; i++)
@ -301,10 +302,10 @@ bool32
Geometry::hasColoredMaterial(void) Geometry::hasColoredMaterial(void)
{ {
for(int32 i = 0; i < this->numMaterials; i++) for(int32 i = 0; i < this->numMaterials; i++)
if(this->materialList[i]->color[0] != 255 || if(this->materialList[i]->color.red != 255 ||
this->materialList[i]->color[1] != 255 || this->materialList[i]->color.green != 255 ||
this->materialList[i]->color[2] != 255 || this->materialList[i]->color.blue != 255 ||
this->materialList[i]->color[3] != 255) this->materialList[i]->color.alpha != 255)
return 1; return 1;
return 0; return 0;
} }
@ -406,8 +407,9 @@ Material*
Material::create(void) Material::create(void)
{ {
Material *mat = (Material*)malloc(PluginBase::s_size); Material *mat = (Material*)malloc(PluginBase::s_size);
assert(mat != NULL);
mat->texture = NULL; mat->texture = NULL;
memset(mat->color, 0xFF, 4); memset(&mat->color, 0xFF, 4);
mat->surfaceProps.ambient = 1.0f; mat->surfaceProps.ambient = 1.0f;
mat->surfaceProps.specular = 1.0f; mat->surfaceProps.specular = 1.0f;
mat->surfaceProps.diffuse = 1.0f; mat->surfaceProps.diffuse = 1.0f;
@ -421,14 +423,12 @@ Material*
Material::clone(void) Material::clone(void)
{ {
Material *mat = Material::create(); Material *mat = Material::create();
mat->color[0] = this->color[0]; mat->color = this->color;
mat->color[1] = this->color[1];
mat->color[2] = this->color[2];
mat->color[3] = this->color[3];
mat->surfaceProps = this->surfaceProps; mat->surfaceProps = this->surfaceProps;
mat->texture = this->texture; if(this->texture){
if(mat->texture) mat->texture = this->texture;
mat->texture->refCount++; mat->texture->refCount++;
}
mat->pipeline = this->pipeline; mat->pipeline = this->pipeline;
mat->copyPlugins(this); mat->copyPlugins(this);
return mat; return mat;
@ -438,7 +438,7 @@ void
Material::destroy(void) Material::destroy(void)
{ {
this->refCount--; this->refCount--;
if(this->refCount == 0){ if(this->refCount <= 0){
this->destructPlugins(); this->destructPlugins();
if(this->texture) if(this->texture)
this->texture->destroy(); this->texture->destroy();
@ -449,7 +449,7 @@ Material::destroy(void)
struct MatStreamData struct MatStreamData
{ {
int32 flags; // unused according to RW int32 flags; // unused according to RW
uint8 color[4]; RGBA color;
int32 unused; int32 unused;
int32 textured; int32 textured;
}; };
@ -465,10 +465,7 @@ Material::streamRead(Stream *stream)
assert(findChunk(stream, ID_STRUCT, NULL, &version)); assert(findChunk(stream, ID_STRUCT, NULL, &version));
stream->read(&buf, sizeof(buf)); stream->read(&buf, sizeof(buf));
Material *mat = Material::create(); Material *mat = Material::create();
mat->color[0] = buf.color[0]; mat->color = buf.color;
mat->color[1] = buf.color[1];
mat->color[2] = buf.color[2];
mat->color[3] = buf.color[3];
if(version < 0x30400){ if(version < 0x30400){
mat->surfaceProps.ambient = 1.0f; mat->surfaceProps.ambient = 1.0f;
mat->surfaceProps.specular = 1.0f; mat->surfaceProps.specular = 1.0f;
@ -501,10 +498,7 @@ Material::streamWrite(Stream *stream)
writeChunkHeader(stream, ID_STRUCT, sizeof(MatStreamData) writeChunkHeader(stream, ID_STRUCT, sizeof(MatStreamData)
+ (rw::version >= 0x30400 ? 12 : 0)); + (rw::version >= 0x30400 ? 12 : 0));
buf.color[0] = this->color[0]; buf.color = this->color;
buf.color[1] = this->color[1];
buf.color[2] = this->color[2];
buf.color[3] = this->color[3];
buf.flags = 0; buf.flags = 0;
buf.unused = 0; buf.unused = 0;
buf.textured = this->texture != NULL; buf.textured = this->texture != NULL;

View File

@ -33,7 +33,8 @@ TexDictionary*
TexDictionary::create(void) TexDictionary::create(void)
{ {
TexDictionary *dict = (TexDictionary*)malloc(PluginBase::s_size); TexDictionary *dict = (TexDictionary*)malloc(PluginBase::s_size);
dict->object.init(6, 0); assert(dict != NULL);
dict->object.init(TexDictionary::ID, 0);
dict->textures.init(); dict->textures.init();
dict->constructPlugins(); dict->constructPlugins();
return dict; return dict;
@ -42,6 +43,8 @@ TexDictionary::create(void)
void void
TexDictionary::destroy(void) TexDictionary::destroy(void)
{ {
FORLIST(lnk, this->textures)
Texture::fromDict(lnk)->destroy();
this->destructPlugins(); this->destructPlugins();
free(this); free(this);
} }
@ -50,7 +53,7 @@ int32
TexDictionary::count(void) TexDictionary::count(void)
{ {
int32 n = 0; int32 n = 0;
FORLIST(l, this->textures) FORLIST(lnk, this->textures)
n++; n++;
return n; return n;
} }
@ -114,6 +117,7 @@ Texture*
Texture::create(Raster *raster) Texture::create(Raster *raster)
{ {
Texture *tex = (Texture*)malloc(PluginBase::s_size); Texture *tex = (Texture*)malloc(PluginBase::s_size);
assert(tex != NULL);
tex->dict = NULL; tex->dict = NULL;
tex->inDict.init(); tex->inDict.init();
memset(tex->name, 0, 32); memset(tex->name, 0, 32);
@ -129,8 +133,12 @@ void
Texture::destroy(void) Texture::destroy(void)
{ {
this->refCount--; this->refCount--;
if(this->refCount == 0){ if(this->refCount <= 0){
this->destructPlugins(); this->destructPlugins();
if(this->dict)
this->inDict.remove();
if(this->raster)
this->raster->destroy();
free(this); free(this);
} }
} }
@ -281,6 +289,7 @@ Image*
Image::create(int32 width, int32 height, int32 depth) Image::create(int32 width, int32 height, int32 depth)
{ {
Image *img = (Image*)malloc(sizeof(*img)); Image *img = (Image*)malloc(sizeof(*img));
assert(img != NULL);
img->flags = 0; img->flags = 0;
img->width = width; img->width = width;
img->height = height; img->height = height;
@ -387,6 +396,7 @@ Image::getFilename(const char *name)
}else }else
for(int i = 0; i < numSearchPaths; i++){ for(int i = 0; i < numSearchPaths; i++){
s = (char*)malloc(strlen(p)+len); s = (char*)malloc(strlen(p)+len);
assert(s != NULL);
strcpy(s, p); strcpy(s, p);
strcat(s, name); strcat(s, name);
f = fopen(s, "r"); f = fopen(s, "r");
@ -569,6 +579,7 @@ Raster*
Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform) Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform)
{ {
Raster *raster = (Raster*)malloc(PluginBase::s_size); Raster *raster = (Raster*)malloc(PluginBase::s_size);
assert(raster != NULL);
raster->platform = platform ? platform : rw::platform; raster->platform = platform ? platform : rw::platform;
raster->type = format & 0x7; raster->type = format & 0x7;
raster->flags = format & 0xF8; raster->flags = format & 0xF8;

View File

@ -1,5 +1,23 @@
namespace rw { namespace rw {
struct RGBA
{
uint8 red;
uint8 green;
uint8 blue;
uint8 alpha;
};
struct V2d
{
float32 x, y;
};
struct V3d
{
float32 x, y, z;
};
struct LLLink struct LLLink
{ {
LLLink *next; LLLink *next;
@ -44,10 +62,11 @@ struct LinkList
} }
}; };
// Have to be careful since the link might be deleted.
#define FORLIST(_link, _list) \ #define FORLIST(_link, _list) \
for(LLLink *_link = (_list).link.next; \ for(LLLink *_next = NULL, *_link = (_list).link.next; \
(_link) != (_list).end(); \ _next = (_link)->next, (_link) != (_list).end(); \
(_link) = (_link)->next) (_link) = _next)
struct Object struct Object
{ {
@ -77,6 +96,7 @@ struct Frame : PluginBase<Frame>
{ {
typedef Frame *(*Callback)(Frame *f, void *data); typedef Frame *(*Callback)(Frame *f, void *data);
enum { ID = 0 };
Object object; Object object;
LinkList objectList; LinkList objectList;
float32 matrix[16]; float32 matrix[16];
@ -90,7 +110,6 @@ struct Frame : PluginBase<Frame>
int32 matflag; int32 matflag;
bool dirty; bool dirty;
// MEM create, clonehiearchy, destroy, destroy hierarchy
static Frame *create(void); static Frame *create(void);
Frame *cloneHierarchy(void); Frame *cloneHierarchy(void);
void destroy(void); void destroy(void);
@ -99,8 +118,7 @@ struct Frame : PluginBase<Frame>
Frame *removeChild(void); Frame *removeChild(void);
Frame *forAllChildren(Callback cb, void *data); Frame *forAllChildren(Callback cb, void *data);
Frame *getParent(void){ Frame *getParent(void){
return (Frame*)this->object.parent; return (Frame*)this->object.parent; }
}
int32 count(void); int32 count(void);
void updateLTM(void); void updateLTM(void);
void setDirty(void); void setDirty(void);
@ -122,6 +140,9 @@ struct ObjectWithFrame : Object
if(f) if(f)
f->objectList.add(&this->inFrame); f->objectList.add(&this->inFrame);
} }
static ObjectWithFrame *fromFrame(LLLink *lnk){
return LLLinkGetData(lnk, ObjectWithFrame, inFrame);
}
}; };
struct HAnimKeyFrame struct HAnimKeyFrame
@ -172,7 +193,6 @@ struct Image
uint8 *pixels; uint8 *pixels;
uint8 *palette; uint8 *palette;
// MEM create, destroy
static Image *create(int32 width, int32 height, int32 depth); static Image *create(int32 width, int32 height, int32 depth);
void destroy(void); void destroy(void);
void allocate(void); void allocate(void);
@ -212,10 +232,8 @@ struct Raster : PluginBase<Raster>
static int32 nativeOffsets[NUM_PLATFORMS]; static int32 nativeOffsets[NUM_PLATFORMS];
// MEM create, destroy
static Raster *create(int32 width, int32 height, int32 depth, int32 format, int32 platform = 0); static Raster *create(int32 width, int32 height, int32 depth, int32 format, int32 platform = 0);
void destroy(void); void destroy(void);
static Raster *createFromImage(Image *image); static Raster *createFromImage(Image *image);
uint8 *lock(int32 level); uint8 *lock(int32 level);
void unlock(int32 level); void unlock(int32 level);
@ -267,12 +285,10 @@ struct Texture : PluginBase<Texture>
uint32 filterAddressing; // VVVVUUUU FFFFFFFF uint32 filterAddressing; // VVVVUUUU FFFFFFFF
int32 refCount; int32 refCount;
// MEM create, addref, destroy
static Texture *create(Raster *raster); static Texture *create(Raster *raster);
void destroy(void); void destroy(void);
static Texture *fromDict(LLLink *lnk){ static Texture *fromDict(LLLink *lnk){
return LLLinkGetData(lnk, Texture, inDict); return LLLinkGetData(lnk, Texture, inDict); }
}
static Texture *streamRead(Stream *stream); static Texture *streamRead(Stream *stream);
bool streamWrite(Stream *stream); bool streamWrite(Stream *stream);
uint32 streamGetSize(void); uint32 streamGetSize(void);
@ -307,12 +323,11 @@ struct SurfaceProperties
struct Material : PluginBase<Material> struct Material : PluginBase<Material>
{ {
Texture *texture; Texture *texture;
uint8 color[4]; RGBA color;
SurfaceProperties surfaceProps; SurfaceProperties surfaceProps;
Pipeline *pipeline; Pipeline *pipeline;
int32 refCount; int32 refCount;
// MEM create, clone, addref, destroy
static Material *create(void); static Material *create(void);
Material *clone(void); Material *clone(void);
void destroy(void); void destroy(void);
@ -414,6 +429,7 @@ struct InstanceDataHeader
struct Geometry : PluginBase<Geometry> struct Geometry : PluginBase<Geometry>
{ {
enum { ID = 8 };
Object object; Object object;
uint32 geoflags; // TODO: rename uint32 geoflags; // TODO: rename
int32 numTriangles; int32 numTriangles;
@ -437,7 +453,6 @@ struct Geometry : PluginBase<Geometry>
int32 refCount; int32 refCount;
// MEM create, addref, destroy
static Geometry *create(int32 numVerts, int32 numTris, uint32 flags); static Geometry *create(int32 numVerts, int32 numTris, uint32 flags);
void destroy(void); void destroy(void);
static Geometry *streamRead(Stream *stream); static Geometry *streamRead(Stream *stream);
@ -494,50 +509,26 @@ void registerSkinPlugin(void);
struct Clump; struct Clump;
struct Light : PluginBase<Light>
{
ObjectWithFrame object;
float32 radius;
float32 color[4];
float32 minusCosAngle;
// clump link handled by plugin in RW
Clump *clump;
LLLink inClump;
// MEM create, destroy
static Light *create(int32 type);
void destroy(void);
void setFrame(Frame *f) { this->object.setFrame(f); }
static Light *fromClump(LLLink *lnk){
return LLLinkGetData(lnk, Light, inClump);
}
static Light *streamRead(Stream *stream);
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
};
struct Atomic : PluginBase<Atomic> struct Atomic : PluginBase<Atomic>
{ {
enum { ID = 1 };
ObjectWithFrame object; ObjectWithFrame object;
Geometry *geometry; Geometry *geometry;
Clump *clump; Clump *clump;
LLLink inClump; LLLink inClump;
ObjPipeline *pipeline; ObjPipeline *pipeline;
// MEM create, clone, destroy
static Atomic *create(void); static Atomic *create(void);
Atomic *clone(void); Atomic *clone(void);
void destroy(void); void destroy(void);
void setFrame(Frame *f) { this->object.setFrame(f); } void setFrame(Frame *f) { this->object.setFrame(f); }
Frame *getFrame(void) { return (Frame*)this->object.parent; } Frame *getFrame(void) { return (Frame*)this->object.parent; }
static Atomic *fromClump(LLLink *lnk){ static Atomic *fromClump(LLLink *lnk){
return LLLinkGetData(lnk, Atomic, inClump); return LLLinkGetData(lnk, Atomic, inClump); }
}
static Atomic *streamReadClump(Stream *stream, static Atomic *streamReadClump(Stream *stream,
Frame **frameList, Geometry **geometryList); Frame **frameList, Geometry **geometryList);
bool streamWriteClump(Stream *stream, bool streamWriteClump(Stream *stream,
Frame **frameList, int32 numFrames); Frame **frameList, int32 numframes);
uint32 streamGetSize(void); uint32 streamGetSize(void);
ObjPipeline *getPipeline(void); ObjPipeline *getPipeline(void);
@ -548,14 +539,77 @@ extern ObjPipeline *defaultPipelines[NUM_PLATFORMS];
void registerAtomicRightsPlugin(void); void registerAtomicRightsPlugin(void);
struct Light : PluginBase<Light>
{
enum { ID = 3 };
ObjectWithFrame object;
float32 radius;
float32 red, green, blue;
float32 minusCosAngle;
// clump link handled by plugin in RW
Clump *clump;
LLLink inClump;
static Light *create(int32 type);
void destroy(void);
void setFrame(Frame *f) { this->object.setFrame(f); }
Frame *getFrame(void){ return (Frame*)this->object.parent; }
static Light *fromClump(LLLink *lnk){
return LLLinkGetData(lnk, Light, inClump); }
void setAngle(float32 angle);
float32 getAngle(void);
void setColor(float32 r, float32 g, float32 b);
static Light *streamRead(Stream *stream);
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
enum Type {
DIRECTIONAL = 1,
AMBIENT,
POINT = 0x80, // positioned
SPOT,
SOFTSPOT,
};
enum Flags {
LIGHTATOMICS = 1,
LIGHTWORLD = 2
};
};
struct Camera : PluginBase<Camera>
{
enum { ID = 4 };
ObjectWithFrame object;
V2d viewWindow;
V2d viewOffset;
float32 nearClip, farClip;
float32 fogPlane;
int32 projection;
Clump *clump;
LLLink inClump;
static Camera *create(void);
Camera *clone(void);
void destroy(void);
void setFrame(Frame *f) { this->object.setFrame(f); }
Frame *getFrame(void){ return (Frame*)this->object.parent; }
static Camera *fromClump(LLLink *lnk){
return LLLinkGetData(lnk, Camera, inClump); }
static Camera *streamRead(Stream *stream);
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
};
struct Clump : PluginBase<Clump> struct Clump : PluginBase<Clump>
{ {
Object object; enum { ID = 2 };
ObjectWithFrame object;
LinkList atomics; LinkList atomics;
LinkList lights; LinkList lights;
// cameras not implemented LinkList cameras;
// MEM create, clone, destroy
static Clump *create(void); static Clump *create(void);
Clump *clone(void); Clump *clone(void);
void destroy(void); void destroy(void);
@ -569,27 +623,29 @@ struct Clump : PluginBase<Clump>
l->clump = this; l->clump = this;
this->lights.append(&l->inClump); this->lights.append(&l->inClump);
} }
int32 countCameras(void);
void addCamera(Camera *c){
c->clump = this;
this->cameras.append(&c->inClump);
}
void setFrame(Frame *f){ void setFrame(Frame *f){
this->object.parent = f; this->object.parent = f; }
}
Frame *getFrame(void){ Frame *getFrame(void){
return (Frame*)this->object.parent; return (Frame*)this->object.parent; }
}
static Clump *streamRead(Stream *stream); static Clump *streamRead(Stream *stream);
bool streamWrite(Stream *stream); bool streamWrite(Stream *stream);
uint32 streamGetSize(void); uint32 streamGetSize(void);
void frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf); void frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf);
void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf); void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf);
}; };
struct TexDictionary : PluginBase<TexDictionary> struct TexDictionary : PluginBase<TexDictionary>
{ {
enum { ID = 6 };
Object object; Object object;
LinkList textures; LinkList textures;
// MEM create, destroy
static TexDictionary *create(void); static TexDictionary *create(void);
void destroy(void); void destroy(void);
int32 count(void); int32 count(void);
@ -603,6 +659,8 @@ struct TexDictionary : PluginBase<TexDictionary>
uint32 streamGetSize(void); uint32 streamGetSize(void);
}; };
extern TexDictionary *currentTexDictionary;
struct Animation; struct Animation;
struct AnimInterpolatorInfo struct AnimInterpolatorInfo
@ -643,8 +701,6 @@ struct AnimInterpolator
AnimInterpolator(Animation *anim); AnimInterpolator(Animation *anim);
}; };
extern TexDictionary *currentTexDictionary;
struct UVAnimKeyFrame struct UVAnimKeyFrame
{ {
UVAnimKeyFrame *prev; UVAnimKeyFrame *prev;

View File

@ -420,7 +420,7 @@ RslGeometryForAllMaterials(RslGeometry *geometry, RslMaterialCallBack fpCallBack
struct RslMaterialChunkInfo struct RslMaterialChunkInfo
{ {
int32 flags; int32 flags;
RslRGBA color; // used RGBA color; // used
int32 unused; int32 unused;
bool32 textured; // used bool32 textured; // used
SurfaceProperties surfaceProps; SurfaceProperties surfaceProps;

View File

@ -42,14 +42,6 @@ typedef RslAtomic *(*RslAtomicCallBack)(RslAtomic *atomic, void *data);
typedef RslMaterial *(*RslMaterialCallBack)(RslMaterial *material, void *data); typedef RslMaterial *(*RslMaterialCallBack)(RslMaterial *material, void *data);
typedef RslTexture *(*RslTextureCallBack)(RslTexture *texture, void *pData); typedef RslTexture *(*RslTextureCallBack)(RslTexture *texture, void *pData);
struct RslRGBA
{
uint8 red;
uint8 green;
uint8 blue;
uint8 alpha;
};
struct RslV3d struct RslV3d
{ {
float32 x, y, z; float32 x, y, z;
@ -311,7 +303,7 @@ struct RslMaterial {
char *texname; char *texname;
RslTexture *texture; RslTexture *texture;
}; };
RslRGBA color; RGBA color;
uint32 refCount; uint32 refCount;
RslMatFX *matfx; RslMatFX *matfx;
}; };

View File

@ -125,10 +125,7 @@ convertMaterial(RslMaterial *m)
Material *rwm; Material *rwm;
rwm = Material::create(); rwm = Material::create();
rwm->color[0] = m->color.red; rwm->color = m->color;
rwm->color[1] = m->color.green;
rwm->color[2] = m->color.blue;
rwm->color[3] = m->color.alpha;
if(m->texture) if(m->texture)
rwm->texture = convertTexture(m->texture); rwm->texture = convertTexture(m->texture);