room101/OBSOLETE/MODEL.CPP

135 lines
4.2 KiB
C++

#include "model.hpp"
#include "polygon.hpp"
/*******************************************************************************
** ModelCreate
*******************************************************************************/
Model
ModelCreate(Picture* skin)
{
Model model;
memset(&model, 0, sizeof(Model));
model.skin = *skin;
return model;
}
/*******************************************************************************
** ModelAnimate
*******************************************************************************/
void
ModelAnimate(Model* model)
{
Vector* A;
Vector* B;
Vector* dst;
Matrix matrix;
Vector vector;
float scale;
int frame, i;
MatrixRotateXYZ(matrix, model->rot.pos);
frame = model->frame.pos[0];
A = model->keyframes[(frame + 0) % NumberOf(model->keyframes)];
B = model->keyframes[(frame + 1) % NumberOf(model->keyframes)];
dst = model->XYZ;
scale = model->frame.pos[0] - frame;
for (i = 0; i < NumberOf(model->XYZ); i++)
{
vector[0] = Interpolate(scale, A[i][0], B[i][0]) * model->scale.pos[0];
vector[1] = Interpolate(scale, A[i][1], B[i][1]) * model->scale.pos[1];
vector[2] = Interpolate(scale, A[i][2], B[i][2]) * model->scale.pos[2];
dst[i][0] = VectorDotProduct(vector, matrix[0]) + model->pos.pos[0];
dst[i][1] = VectorDotProduct(vector, matrix[1]) + model->pos.pos[1];
dst[i][2] = VectorDotProduct(vector, matrix[2]) + model->pos.pos[2];
}
}
/*******************************************************************************
** ModelRead
*******************************************************************************/
Model
ModelRead(Picture* skin)
{
Model model = ModelCreate(skin);
model.keyframes = VectorArrayArrayRead(stdin);
model.XYZ = (Vector*)MemoryAlloc(NumberOf(model.keyframes[0]), sizeof(Vector));
model.polys = MeshFaceArrayRead();
model.UVW = (Vector*)MemoryRead(stdin);
ModelAnimate(&model);
return model;
}
/*******************************************************************************
** ModelRender
*******************************************************************************/
void
ModelRender(Model* model, Camera* camera)
{
Vertex t1[POLYGON_MAX];
Vertex t2[POLYGON_MAX];
MeshFace* poly;
int i, j, n, vid;
assert(model && camera);
ModelAnimate(model);
PolygonTransform(model->XYZ, model->XYZ, NumberOf(model->XYZ), camera->matrix);
for (i = 0; i < NumberOf(model->polys); i++)
{
poly = &model->polys[i];
n = NumberOf(poly->ids);
for (j = 0; j < n; j++)
{
vid = poly->ids[j];
t1[j][0][0] = model->XYZ[vid][0];
t1[j][0][1] = model->XYZ[vid][1];
t1[j][0][2] = model->XYZ[vid][2];
t1[j][1][0] = model->UVW[vid][0];
t1[j][1][1] = model->UVW[vid][1];
}
n = VertexArrayClipToFrustum2(t2, t1, n);
if (n >= POLYGON_MIN)
{
for (j = 0; j < n; j++)
{
t2[j][1][0] *= model->skin.width;
t2[j][1][1] *= model->skin.height;
t2[j][1][2] = 2500000.0f / VectorDotProduct(t2[j][0], t2[j][0]);
t2[j][1][2] = Min(t2[j][1][2], 255.0f);
}
VertexArrayProject(t2, n, camera->origin);
/*
** Simple backface removal. Could be done better. Maybe?
*/
if (
(t2[2][0][0] - t2[1][0][0]) * (t2[0][0][1] - t2[1][0][1]) -
(t2[2][0][1] - t2[1][0][1]) * (t2[0][0][0] - t2[1][0][0]) > 0)
{
VertexArrayScanXYZUVW(t2, n);
DDATextureMap(camera->fb, &model->skin, camera->zb);
}
}
}
}
/*******************************************************************************
** ModelTick
*******************************************************************************/
void
ModelTick(Model* model)
{
assert(model != NULL);
MotionTick(&model->pos);
MotionTick(&model->rot);
MotionTick(&model->frame);
}