implemented projection in Camera

This commit is contained in:
aap 2016-02-14 20:56:05 +01:00
parent ad81510267
commit cc77487fc0
6 changed files with 282 additions and 94 deletions

View File

@ -30,12 +30,8 @@ Frame::create(void)
f->child = NULL;
f->next = NULL;
f->root = f;
for(int i = 0; i < 16; i++)
f->matrix[i] = 0.0f;
f->matrix[0] = 1.0f;
f->matrix[5] = 1.0f;
f->matrix[10] = 1.0f;
f->matrix[15] = 1.0f;
f->matrix.setIdentity();
f->ltm.setIdentity();
f->constructPlugins();
return f;
}
@ -166,7 +162,7 @@ syncRecurse(Frame *frame, uint8 flags)
for(; frame; frame = frame->next){
flg = flags | frame->object.privateFlags;
if(flg & Frame::SUBTREESYNCLTM){
matrixMult(frame->ltm, frame->getParent()->ltm, frame->matrix);
Matrix::mult(&frame->ltm, &frame->getParent()->ltm, &frame->matrix);
frame->object.privateFlags &= ~Frame::SUBTREESYNCLTM;
}
syncRecurse(frame->child, flg);
@ -179,11 +175,11 @@ Frame::syncHierarchyLTM(void)
Frame *child;
uint8 flg;
if(this->object.privateFlags & Frame::SUBTREESYNCLTM)
memcpy(this->ltm, this->matrix, 64);
this->ltm = this->matrix;
for(child = this->child; child; child = child->next){
flg = this->object.privateFlags | child->object.privateFlags;
if(flg & Frame::SUBTREESYNCLTM){
matrixMult(child->ltm, this->ltm, child->matrix);
Matrix::mult(&child->ltm, &this->ltm, &child->matrix);
child->object.privateFlags &= ~Frame::SUBTREESYNCLTM;
}
syncRecurse(child, flg);
@ -191,12 +187,12 @@ Frame::syncHierarchyLTM(void)
this->object.privateFlags &= ~Frame::SYNCLTM;
}
float*
Matrix*
Frame::getLTM(void)
{
if(this->root->object.privateFlags & Frame::HIERARCHYSYNCLTM)
this->root->syncHierarchyLTM();
return this->ltm;
return &this->ltm;
}
void
@ -224,7 +220,8 @@ Frame::cloneAndLink(Frame *clonedroot)
if(clonedroot == NULL)
clonedroot = frame;
frame->object.copy(&this->object);
memcpy(frame->matrix, this->matrix, sizeof(this->matrix));
frame->matrix = this->matrix;
//memcpy(frame->matrix, this->matrix, sizeof(this->matrix));
frame->root = clonedroot;
this->root = frame; // Remember cloned frame
for(Frame *child = this->child; child; child = child->next){
@ -447,8 +444,7 @@ Clump::streamWrite(Stream *stream)
struct FrameStreamData
{
float32 mat[9];
float32 pos[3];
V3d right, up, at, pos;
int32 parent;
int32 matflag;
};
@ -490,6 +486,16 @@ Clump::streamGetSize(void)
return size;
}
void
Clump::render(void)
{
Atomic *a;
FORLIST(lnk, this->atomics){
a = Atomic::fromClump(lnk);
if(a->object.flags & Atomic::RENDER)
a->render();
}
}
void
Clump::frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf)
@ -504,22 +510,14 @@ Clump::frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf)
Frame *f;
frameList[i] = f = Frame::create();
stream->read(&buf, sizeof(buf));
f->matrix[0] = buf.mat[0];
f->matrix[1] = buf.mat[1];
f->matrix[2] = buf.mat[2];
f->matrix[3] = 0.0f;
f->matrix[4] = buf.mat[3];
f->matrix[5] = buf.mat[4];
f->matrix[6] = buf.mat[5];
f->matrix[7] = 0.0f;
f->matrix[8] = buf.mat[6];
f->matrix[9] = buf.mat[7];
f->matrix[10] = buf.mat[8];
f->matrix[11] = 0.0f;
f->matrix[12] = buf.pos[0];
f->matrix[13] = buf.pos[1];
f->matrix[14] = buf.pos[2];
f->matrix[15] = 1.0f;
f->matrix.right = buf.right;
f->matrix.rightw = 0.0f;
f->matrix.up = buf.up;
f->matrix.upw = 0.0f;
f->matrix.at = buf.at;
f->matrix.atw = 0.0f;
f->matrix.pos = buf.pos;
f->matrix.posw = 1.0f;
//f->matflag = buf.matflag;
if(buf.parent >= 0)
frameList[buf.parent]->addChild(f);
@ -546,18 +544,10 @@ Clump::frameListStreamWrite(Stream *stream, Frame **frameList, int32 numFrames)
stream->writeU32(numFrames);
for(int32 i = 0; i < numFrames; i++){
Frame *f = frameList[i];
buf.mat[0] = f->matrix[0];
buf.mat[1] = f->matrix[1];
buf.mat[2] = f->matrix[2];
buf.mat[3] = f->matrix[4];
buf.mat[4] = f->matrix[5];
buf.mat[5] = f->matrix[6];
buf.mat[6] = f->matrix[8];
buf.mat[7] = f->matrix[9];
buf.mat[8] = f->matrix[10];
buf.pos[0] = f->matrix[12];
buf.pos[1] = f->matrix[13];
buf.pos[2] = f->matrix[14];
buf.right = f->matrix.right;
buf.up = f->matrix.up;
buf.at = f->matrix.at;
buf.pos = f->matrix.pos;
buf.parent = findPointer(f->getParent(), (void**)frameList,
numFrames);
buf.matflag = 0; //f->matflag;
@ -580,17 +570,9 @@ Atomic::create(void)
atomic->geometry = NULL;
atomic->pipeline = NULL;
atomic->renderCB = Atomic::defaultRenderCB;
atomic->object.flags = Atomic::COLLISIONTEST | Atomic::RENDER;
atomic->constructPlugins();
// flags:
// rpATOMICCOLLISIONTEST = 0x01, /**<A generic collision flag to indicate
// * that the atomic should be considered
// * in collision tests.
// */
// rpATOMICRENDER = 0x04, /**<The atomic is rendered if it is
// * in the view frustum.
// */
// private flags:
// rpATOMICPRIVATEWORLDBOUNDDIRTY = 0x01
return atomic;
@ -638,6 +620,7 @@ Atomic::streamReadClump(Stream *stream,
atomic->geometry = Geometry::streamRead(stream);
}else
atomic->geometry = geometryList[buf[1]];
atomic->object.flags = buf[2];
atomicRights[0] = 0;
atomic->streamReadPlugins(stream);
@ -649,7 +632,7 @@ Atomic::streamReadClump(Stream *stream,
bool
Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames)
{
int32 buf[4] = { 0, 0, 5, 0 };
int32 buf[4] = { 0, 0, 0, 0 };
Clump *c = this->clump;
if(c == NULL)
return false;
@ -658,6 +641,7 @@ Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames)
buf[0] = findPointer(this->getFrame(), (void**)frameList, numFrames);
if(version < 0x30400){
buf[1] = this->object.flags;
stream->write(buf, sizeof(int[3]));
this->geometry->streamWrite(stream);
}else{
@ -669,6 +653,7 @@ Atomic::streamWriteClump(Stream *stream, Frame **frameList, int32 numFrames)
}
return false;
foundgeo:
buf[2] = this->object.flags;
stream->write(buf, sizeof(buf));
}
@ -864,7 +849,7 @@ Camera::create(void)
cam->nearPlane = 0.05f;
cam->farPlane = 10.0f;
cam->fogPlane = 5.0f;
cam->projection = 1;
cam->projection = Camera::PERSPECTIVE;
cam->constructPlugins();
return cam;
}
@ -942,4 +927,56 @@ Camera::streamGetSize(void)
return 12 + sizeof(CameraChunkData) + 12 + this->streamGetPluginSize();
}
void
Camera::updateProjectionMatrix(void)
{
float32 invwx = 1.0f/this->viewWindow.x;
float32 invwy = 1.0f/this->viewWindow.y;
float32 invz = 1.0f/(this->farPlane-this->nearPlane);
if(rw::platform == PLATFORM_D3D8 || rw::platform == PLATFORM_D3D9 ||
rw::platform == PLATFORM_XBOX){
// is this all really correct?
this->projMat[0] = invwx;
this->projMat[1] = 0.0f;
this->projMat[2] = 0.0f;
this->projMat[3] = 0.0f;
this->projMat[4] = 0.0f;
this->projMat[5] = invwy;
this->projMat[6] = 0.0f;
this->projMat[7] = 0.0f;
if(this->projection == PERSPECTIVE){
this->projMat[8] = this->viewOffset.x*invwx;
this->projMat[9] = this->viewOffset.y*invwy;
this->projMat[10] = this->farPlane*invz;
this->projMat[11] = 1.0f;
this->projMat[12] = 0.0f;
this->projMat[13] = 0.0f;
this->projMat[14] = -this->nearPlane*this->projMat[10];
this->projMat[15] = 0.0f;
}else{
this->projMat[8] = 0.0f;
this->projMat[9] = 0.0f;
this->projMat[10] = invz;
this->projMat[11] = 0.0f;
this->projMat[12] = this->viewOffset.x*invwx;
this->projMat[13] = this->viewOffset.y*invwy;
this->projMat[14] = -this->nearPlane*this->projMat[10];
this->projMat[15] = 1.0f;
}
}
}
void
Camera::setFOV(float32 fov, float32 ratio)
{
float32 a = tan(fov*3.14159f/360.0f);
this->viewWindow.x = a;
this->viewWindow.y = a/ratio;
this->viewOffset.set(0.0f, 0.0f);
}
}

View File

@ -276,13 +276,28 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
destroyNativeData(geo, 0, 0);
}
static void
render(rw::ObjPipeline *rwpipe, Atomic *atomic)
{
ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0)
pipe->instance(atomic);
assert(geo->instData != NULL);
assert(geo->instData->platform == PLATFORM_D3D8);
if(pipe->renderCB)
pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData);
}
ObjPipeline::ObjPipeline(uint32 platform)
: rw::ObjPipeline(platform)
{
this->impl.instance = d3d8::instance;
this->impl.uninstance = d3d8::uninstance;
this->impl.render = d3d8::render;
this->instanceCB = NULL;
this->uninstanceCB = NULL;
this->renderCB = NULL;
}
void
@ -360,6 +375,7 @@ makeDefaultPipeline(void)
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB;
return pipe;
}
@ -369,6 +385,7 @@ makeSkinPipeline(void)
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB;
pipe->pluginID = ID_SKIN;
pipe->pluginData = 1;
return pipe;
@ -380,6 +397,7 @@ makeMatFXPipeline(void)
ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8);
pipe->instanceCB = defaultInstanceCB;
pipe->uninstanceCB = defaultUninstanceCB;
pipe->renderCB = defaultRenderCB;
pipe->pluginID = ID_MATFX;
pipe->pluginData = 0;
return pipe;

View File

@ -2,6 +2,7 @@
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cmath>
#include "rwbase.h"
#include "rwplugin.h"
@ -30,6 +31,8 @@ int32 build = 0xFFFF;
#endif
char *debugFile = NULL;
static Matrix identMat;
void
initialize(void)
{
@ -49,6 +52,55 @@ initialize(void)
d3d9::makeDefaultPipeline();
Frame::dirtyList.init();
identMat.right.set(1.0f, 0.0f, 0.0f);
identMat.rightw = 0.0f;
identMat.up.set(0.0f, 1.0f, 0.0f);
identMat.upw = 0.0f;
identMat.at.set(0.0f, 0.0f, 1.0f);
identMat.atw = 0.0f;
identMat.pos.set(0.0f, 0.0f, 0.0f);
identMat.posw = 1.0f;
}
float32
V3d::length(void)
{
return sqrt(this->x*this->x+this->y*this->y+this->z*this->z);
}
V3d
V3d::normalize(void)
{
return V3d::scale(this, 1.0f/this->length());
}
V3d
V3d::cross(V3d *a, V3d *b)
{
V3d res;
res.x = a->y*b->z - a->z*b->y;
res.y = a->z*b->x - a->x*b->z;
res.z = a->x*b->y - a->y*b->x;
return res;
}
void
Matrix::setIdentity(void)
{
*this = identMat;
}
void
Matrix::mult(Matrix *m1, Matrix *m2, Matrix *m3)
{
matrixMult((float32*)m1, (float32*)m2, (float32*)m3);
}
void
Matrix::invert(Matrix *m1, Matrix *m2)
{
matrixInvert((float32*)m1, (float32*)m2);
}
void
@ -232,6 +284,19 @@ matrixInvert(float32 *out, float32 *m)
out[i] = inv[i] * det;
}
void
matrixPrint(float32 *mat)
{
printf("[ [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
" [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
" [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
" [ %8.4f, %8.4f, %8.4f, %8.4f ] ]\n",
mat[0], mat[4], mat[8], mat[12],
mat[1], mat[5], mat[9], mat[13],
mat[2], mat[6], mat[10], mat[14],
mat[3], mat[7], mat[11], mat[15]);
}
int32
Stream::writeI8(int8 val)
{

View File

@ -34,6 +34,93 @@ typedef uint32 uint;
#define nelem(A) (sizeof(A) / sizeof A[0])
struct RGBA
{
uint8 red;
uint8 green;
uint8 blue;
uint8 alpha;
};
struct RGBAf
{
float32 red;
float32 green;
float32 blue;
float32 alpha;
};
struct V2d
{
float32 x, y;
void set(float32 x, float32 y){
this->x = x; this->y = y; }
};
struct V3d
{
float32 x, y, z;
void set(float32 x, float32 y, float32 z){
this->x = x; this->y = y; this->z = z; }
static V3d sub(V3d *a, V3d *b){
V3d res;
res.x = a->x - b->x;
res.y = a->y - b->y;
res.z = a->z - b->z;
return res;
}
static V3d add(V3d *a, V3d *b){
V3d res;
res.x = a->x + b->x;
res.y = a->y + b->y;
res.z = a->z + b->z;
return res;
}
static V3d scale(V3d *a, float32 r){
V3d res;
res.x = a->x*r;
res.y = a->y*r;
res.z = a->z*r;
return res;
}
float32 length(void);
V3d normalize(void);
static V3d cross(V3d *a, V3d *b);
};
struct Quat
{
float32 w, x, y, z;
void set(float32 w, float32 x, float32 y, float32 z){
this->w = w; this->x = x; this->y = y; this->z = z; }
};
struct Matrix
{
V3d right;
float32 rightw;
V3d up;
float32 upw;
V3d at;
float32 atw;
V3d pos;
float32 posw;
void setIdentity(void);
// not very pretty :/
static void mult(Matrix *m1, Matrix *m2, Matrix *m3);
static void invert(Matrix *m1, Matrix *m2);
};
void matrixIdentity(float32 *mat);
int matrixEqual(float32 *m1, float32 *m2);
int matrixIsIdentity(float32 *mat);
void matrixMult(float32 *out, float32 *a, float32 *b);
void vecTrans(float32 *out, float32 *mat, float32 *vec);
void matrixTranspose(float32 *out, float32 *in);
void matrixInvert(float32 *out, float32 *in);
void matrixPrint(float32 *mat);
class Stream
{
public:
@ -155,14 +242,6 @@ extern char *debugFile;
void initialize(void);
void matrixIdentity(float32 *mat);
int matrixEqual(float32 *m1, float32 *m2);
int matrixIsIdentity(float32 *mat);
void matrixMult(float32 *out, float32 *a, float32 *b);
void vecTrans(float32 *out, float32 *mat, float32 *vec);
void matrixTranspose(float32 *out, float32 *in);
void matrixInvert(float32 *out, float32 *in);
// 0x04000000 3.1
// 0x08000000 3.2
// 0x0C000000 3.3

View File

@ -40,10 +40,15 @@ class ObjPipeline : public rw::ObjPipeline
public:
void (*instanceCB)(Geometry *geo, InstanceData *header);
void (*uninstanceCB)(Geometry *geo, InstanceData *header);
void (*renderCB)(Atomic *atomic, InstanceDataHeader *header);
ObjPipeline(uint32 platform);
};
void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header);
void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
ObjPipeline *makeDefaultPipeline(void);
ObjPipeline *makeSkinPipeline(void);

View File

@ -2,36 +2,6 @@
namespace rw {
struct RGBA
{
uint8 red;
uint8 green;
uint8 blue;
uint8 alpha;
};
struct RGBAf
{
float32 red;
float32 green;
float32 blue;
float32 alpha;
};
struct V2d
{
float32 x, y;
void set(float32 x, float32 y){
this->x = x; this->y = y; }
};
struct V3d
{
float32 x, y, z;
void set(float32 x, float32 y, float32 z){
this->x = x; this->y = y; this->z = z; }
};
struct LLLink
{
LLLink *next;
@ -130,8 +100,10 @@ struct Frame : PluginBase<Frame>
Object object;
LLLink inDirtyList;
LinkList objectList;
float32 matrix[16];
float32 ltm[16];
Matrix matrix;
Matrix ltm;
//float32 matrix[16];
//float32 ltm[16];
Frame *child;
Frame *next;
@ -149,7 +121,7 @@ struct Frame : PluginBase<Frame>
Frame *getParent(void){
return (Frame*)this->object.parent; }
int32 count(void);
float *getLTM(void);
Matrix *getLTM(void);
void updateObjects(void);
void syncHierarchyLTM(void);
@ -590,6 +562,10 @@ struct Atomic : PluginBase<Atomic>
{
typedef void (*RenderCB)(Atomic *atomic);
enum { ID = 1 };
enum {
COLLISIONTEST = 0x01, // unused here
RENDER = 0x04
};
ObjectWithFrame object;
Geometry *geometry;
@ -662,12 +638,15 @@ struct Light : PluginBase<Light>
struct Camera : PluginBase<Camera>
{
enum { ID = 4 };
enum { PERSPECTIVE = 1, PARALLEL };
ObjectWithFrame object;
V2d viewWindow;
V2d viewOffset;
float32 nearPlane, farPlane;
float32 fogPlane;
int32 projection;
float32 projMat[16];
Clump *clump;
LLLink inClump;
@ -682,6 +661,10 @@ struct Camera : PluginBase<Camera>
static Camera *streamRead(Stream *stream);
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
void updateProjectionMatrix(void);
// fov in degrees
void setFOV(float32 fov, float32 ratio);
};
struct Clump : PluginBase<Clump>
@ -717,6 +700,7 @@ struct Clump : PluginBase<Clump>
static Clump *streamRead(Stream *stream);
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
void render(void);
void frameListStreamRead(Stream *stream, Frame ***flp, int32 *nf);
void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf);