diff --git a/src/camera.cpp b/src/camera.cpp index 12beb7b..d55fc95 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -31,6 +31,26 @@ cameraSync(ObjectWithFrame*) { } +void +worldBeginUpdateCB(Camera *cam) +{ + engine.currentWorld = cam->world; + cam->originalBeginUpdate(cam); +} + +void +worldEndUpdateCB(Camera *cam) +{ + cam->originalEndUpdate(cam); +} + +static void +worldCameraSync(ObjectWithFrame *obj) +{ + Camera *camera = (Camera*)obj; + camera->originalSync(obj); +} + Camera* Camera::create(void) { @@ -41,17 +61,27 @@ Camera::create(void) } cam->object.object.init(Camera::ID, 0); cam->object.syncCB = cameraSync; + cam->beginUpdateCB = defaultBeginUpdateCB; + cam->endUpdateCB = defaultEndUpdateCB; cam->viewWindow.set(1.0f, 1.0f); cam->viewOffset.set(0.0f, 0.0f); cam->nearPlane = 0.05f; cam->farPlane = 10.0f; cam->fogPlane = 5.0f; cam->projection = Camera::PERSPECTIVE; + + // clump extension cam->clump = nil; cam->inClump.init(); - cam->beginUpdateCB = defaultBeginUpdateCB; - cam->endUpdateCB = defaultEndUpdateCB; + // world extension + cam->world = nil; + cam->originalSync = cam->object.syncCB; + cam->originalBeginUpdate = cam->beginUpdateCB; + cam->originalEndUpdate = cam->endUpdateCB; + cam->object.syncCB = worldCameraSync; + cam->beginUpdateCB = worldBeginUpdateCB; + cam->endUpdateCB = worldEndUpdateCB; cam->constructPlugins(); return cam; @@ -138,6 +168,7 @@ Camera::streamGetSize(void) return 12 + sizeof(CameraChunkData) + 12 + this->streamGetPluginSize(); } +// TODO: remove void Camera::updateProjectionMatrix(void) { diff --git a/src/clump.cpp b/src/clump.cpp index 9f8d69b..6f9b867 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -320,6 +320,14 @@ atomicSync(ObjectWithFrame*) { } + +static void +worldAtomicSync(ObjectWithFrame *obj) +{ + Atomic *atomic = (Atomic*)obj; + atomic->originalSync(obj); +} + Atomic* Atomic::create(void) { @@ -338,6 +346,12 @@ Atomic::create(void) atomic->pipeline = nil; atomic->renderCB = Atomic::defaultRenderCB; atomic->object.object.flags = Atomic::COLLISIONTEST | Atomic::RENDER; + + // World extension + atomic->world = nil; + atomic->originalSync = atomic->object.syncCB; + atomic->object.syncCB = worldAtomicSync; + atomic->constructPlugins(); return atomic; } diff --git a/src/light.cpp b/src/light.cpp index 6b30957..dd28824 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -16,6 +16,13 @@ lightSync(ObjectWithFrame*) { } +static void +worldLightSync(ObjectWithFrame *obj) +{ + Light *light = (Light*)obj; + light->originalSync(obj); +} + Light* Light::create(int32 type) { @@ -34,8 +41,17 @@ Light::create(int32 type) light->minusCosAngle = 1.0f; light->object.object.privateFlags = 1; light->object.object.flags = LIGHTATOMICS | LIGHTWORLD; + light->inWorld.init(); + + // clump extension light->clump = nil; light->inClump.init(); + + // world extension + light->world = nil; + light->originalSync = light->object.syncCB; + light->object.syncCB = worldLightSync; + light->constructPlugins(); return light; } @@ -46,6 +62,7 @@ Light::destroy(void) this->destructPlugins(); if(this->clump) this->inClump.remove(); + // we do not remove from world, be careful free(this); } diff --git a/src/rwbase.cpp b/src/rwbase.cpp index 3aad377..ee29211 100644 --- a/src/rwbase.cpp +++ b/src/rwbase.cpp @@ -137,6 +137,15 @@ Matrix::setIdentity(void) *this = identMat; } +void +Matrix::pointInDirection(const V3d &d, const V3d &up) +{ + // this->right is really pointing left + this->at = normalize(d); + this->right = normalize(cross(up, this->at)); + this->up = cross(this->at, this->right); +} + V3d Matrix::transPoint(const V3d &p) { diff --git a/src/rwbase.h b/src/rwbase.h index 261847b..31c029d 100644 --- a/src/rwbase.h +++ b/src/rwbase.h @@ -53,6 +53,25 @@ struct RGBAf float32 alpha; }; +inline void convColor(RGBA *i, RGBAf *f){ + int32 c; + c = (int32)(f->red*255.0f + 0.5f); + i->red = (uint8)c; + c = (int32)(f->green*255.0f + 0.5f); + i->green = (uint8)c; + c = (int32)(f->blue*255.0f + 0.5f); + i->blue = (uint8)c; + c = (int32)(f->alpha*255.0f + 0.5f); + i->alpha = (uint8)c; +} + +inline void convColor(RGBAf *f, RGBA *i){ + f->red = i->red/255.0f; + f->green = i->green/255.0f; + f->blue = i->blue/255.0f; + f->alpha = i->alpha/255.0f; +} + struct V2d { float32 x, y; @@ -122,6 +141,7 @@ struct Matrix static Matrix makeRotation(const Quat &q); void setIdentity(void); + void pointInDirection(const V3d &d, const V3d &up); V3d transPoint(const V3d &p); V3d transVec(const V3d &v); bool32 isIdentity(void); diff --git a/src/rwengine.h b/src/rwengine.h index 742563c..fb7e7dd 100644 --- a/src/rwengine.h +++ b/src/rwengine.h @@ -4,7 +4,8 @@ namespace rw { struct Engine { - Camera *currentCamera; + void *currentCamera; + void *currentWorld; }; extern Engine engine; diff --git a/src/rwobjects.h b/src/rwobjects.h index 9b5d090..9f4d96d 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -148,9 +148,11 @@ Frame **makeFrameList(Frame *frame, Frame **flist); struct ObjectWithFrame { + typedef void (*Sync)(ObjectWithFrame*); + Object object; LLLink inFrame; - void (*syncCB)(ObjectWithFrame*); + Sync syncCB; void setFrame(Frame *f){ if(this->object.parent) @@ -237,6 +239,14 @@ struct Raster : PluginBase PAL4 = 0x4000, MIPMAP = 0x8000 }; + enum Type { + NORMAL = 0x00, + ZBUFFER = 0x01, + CAMERA = 0x02, + TEXTURE = 0x04, + CAMERATEXTURE = 0x05, + DONTALLOCATE = 0x80, + }; }; extern bool32 loadTextures; @@ -403,6 +413,10 @@ struct Geometry : PluginBase MODULATE = 0x40, TEXTURED2 = 0x80, NATIVE = 0x01000000, + // Just for documentation: RW sets this flag + // to prevent rendering when executing a pipeline, + // so only instancing will occur. + // librw's pipelines are different so it's unused here. NATIVEINSTANCE = 0x02000000 }; }; @@ -411,6 +425,7 @@ void registerMeshPlugin(void); void registerNativeDataPlugin(void); struct Clump; +struct World; struct Atomic : PluginBase { @@ -431,6 +446,9 @@ struct Atomic : PluginBase ObjPipeline *pipeline; RenderCB renderCB; + World *world; + ObjectWithFrame::Sync originalSync; + static Atomic *create(void); Atomic *clone(void); void destroy(void); @@ -463,17 +481,24 @@ struct Light : PluginBase float32 radius; RGBAf color; float32 minusCosAngle; + LLLink inWorld; - // clump link handled by plugin in RW + // clump extension Clump *clump; LLLink inClump; + // world extension + World *world; + ObjectWithFrame::Sync originalSync; + static Light *create(int32 type); void destroy(void); void setFrame(Frame *f) { this->object.setFrame(f); } Frame *getFrame(void){ return (Frame*)this->object.object.parent; } static Light *fromClump(LLLink *lnk){ return LLLinkGetData(lnk, Light, inClump); } + static Light *fromWorld(LLLink *lnk){ + return LLLinkGetData(lnk, Light, inWorld); } void setAngle(float32 angle); float32 getAngle(void); void setColor(float32 r, float32 g, float32 b); @@ -501,18 +526,26 @@ struct Camera : PluginBase enum { PERSPECTIVE = 1, PARALLEL }; ObjectWithFrame object; + void (*beginUpdateCB)(Camera*); + void (*endUpdateCB)(Camera*); V2d viewWindow; V2d viewOffset; float32 nearPlane, farPlane; float32 fogPlane; int32 projection; + // TODO: remove this? float32 projMat[16]; + // clump link handled by plugin in RW Clump *clump; LLLink inClump; - void (*beginUpdateCB)(Camera*); - void (*endUpdateCB)(Camera*); + // world extension + /* 3 unknowns */ + World *world; + ObjectWithFrame::Sync originalSync; + void (*originalBeginUpdate)(Camera*); + void (*originalEndUpdate)(Camera*); static Camera *create(void); Camera *clone(void); @@ -540,6 +573,8 @@ struct Clump : PluginBase LinkList lights; LinkList cameras; + World *world; + static Clump *create(void); Clump *clone(void); void destroy(void); @@ -568,6 +603,19 @@ struct Clump : PluginBase void render(void); }; +// A bit of a stub right now +struct World : PluginBase +{ + enum { ID = 7 }; + Object object; + LinkList lights; // these have positions (type >= 0x80) + LinkList directionalLights; // these do not (type < 0x80) + + static World *create(void); + void addLight(Light *light); + void addCamera(Camera *cam); +}; + struct TexDictionary : PluginBase { enum { ID = 6 };