add oversampler
This commit is contained in:
762
oversampling/WDL/plush2/pl_cam.cpp
Normal file
762
oversampling/WDL/plush2/pl_cam.cpp
Normal file
@@ -0,0 +1,762 @@
|
||||
/******************************************************************************
|
||||
Plush Version 1.2
|
||||
cam.c
|
||||
Camera and Rendering
|
||||
Copyright (c) 1996-2000, Justin Frankel
|
||||
******************************************************************************/
|
||||
|
||||
#include "plush.h"
|
||||
|
||||
|
||||
#include "../lice/lice_extended.h"
|
||||
|
||||
#include "../mergesort.h"
|
||||
|
||||
#define MACRO_plMatrixApply(m,x,y,z,outx,outy,outz) \
|
||||
( outx ) = ( x )*( m )[0] + ( y )*( m )[1] + ( z )*( m )[2] + ( m )[3];\
|
||||
( outy ) = ( x )*( m )[4] + ( y )*( m )[5] + ( z )*( m )[6] + ( m )[7];\
|
||||
( outz ) = ( x )*( m )[8] + ( y )*( m )[9] + ( z )*( m )[10] + ( m )[11]
|
||||
|
||||
#define MACRO_plDotProduct(x1,y1,z1,x2,y2,z2) \
|
||||
((( x1 )*( x2 ))+(( y1 )*( y2 ))+(( z1 )*( z2 )))
|
||||
|
||||
#define MACRO_plNormalizeVector(x,y,z) { \
|
||||
double length; \
|
||||
length = ( x )*( x )+( y )*( y )+( z )*( z ); \
|
||||
if (length > 0.0000000001) { \
|
||||
double __l = 1.0/sqrt(length); \
|
||||
( x ) *= __l; \
|
||||
( y ) *= __l; \
|
||||
( z ) *= __l; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
static void _FindNormal(double x2, double x3,double y2, double y3,
|
||||
double zv, double *res) {
|
||||
res[0] = zv*(y2-y3);
|
||||
res[1] = zv*(x3-x2);
|
||||
res[2] = x2*y3 - y2*x3;
|
||||
}
|
||||
|
||||
|
||||
void pl_Cam::SetTarget(pl_Float x, pl_Float y, pl_Float z) {
|
||||
double dx, dy, dz;
|
||||
dx = x - X;
|
||||
dy = y - Y;
|
||||
dz = z - Z;
|
||||
Roll = 0;
|
||||
if (dz > 0.0001f) {
|
||||
Pan = (pl_Float) (-atan(dx/dz)*(180.0/PL_PI));
|
||||
dz /= cos(Pan*(PL_PI/180.0));
|
||||
Pitch = (pl_Float) (atan(dy/dz)*(180.0/PL_PI));
|
||||
} else if (dz < -0.0001f) {
|
||||
Pan = (pl_Float) (180.0-atan(dx/dz)*(180.0/PL_PI));
|
||||
dz /= cos((Pan-180.0f)*(PL_PI/180.0));
|
||||
Pitch = (pl_Float) (-atan(dy/dz)*(180.0/PL_PI));
|
||||
} else {
|
||||
Pan = 90.0f;
|
||||
Pitch = (pl_Float) (atan2(dy,-dx) * (180.0 / PL_PI));
|
||||
Roll = -90.0f;
|
||||
}
|
||||
GenMatrix = true;
|
||||
}
|
||||
|
||||
void pl_Cam::RecalcFrustum(int fbw, int fbh)
|
||||
{
|
||||
const int cx = (CenterX*m_lastFBScaling)/256 + fbw/2;
|
||||
const int cy = (CenterY*m_lastFBScaling)/256 + fbh/2;
|
||||
m_lastCX = cx;
|
||||
m_lastCY = cy;
|
||||
|
||||
m_adj_asp = 1.0 / AspectRatio;
|
||||
m_fovfactor = CalcFOVFactor(fbw);
|
||||
memset(m_clipPlanes,0,sizeof(m_clipPlanes));
|
||||
|
||||
/* Back */
|
||||
m_clipPlanes[0][2] = -1.0;
|
||||
m_clipPlanes[0][3] = -ClipBack;
|
||||
|
||||
/* Left */
|
||||
m_clipPlanes[1][3] = 0.00000001;
|
||||
if (cx == 0) m_clipPlanes[1][0] = 1.0;
|
||||
else
|
||||
{
|
||||
_FindNormal(-100,-100,
|
||||
100, -100,
|
||||
m_fovfactor*100.0/cx,
|
||||
m_clipPlanes[1]);
|
||||
if (cx < 0)
|
||||
{
|
||||
m_clipPlanes[1][0] = -m_clipPlanes[1][0];
|
||||
m_clipPlanes[1][1] = -m_clipPlanes[1][1];
|
||||
m_clipPlanes[1][2] = -m_clipPlanes[1][2];
|
||||
}
|
||||
}
|
||||
|
||||
/* Right */
|
||||
m_clipPlanes[2][3] = 0.00000001;
|
||||
if (fbw == cx) m_clipPlanes[2][0] = -1.0;
|
||||
else
|
||||
{
|
||||
_FindNormal(100,100,
|
||||
-100, 100,
|
||||
m_fovfactor*100.0/(fbw-cx),
|
||||
m_clipPlanes[2]);
|
||||
if (cx > fbw)
|
||||
{
|
||||
m_clipPlanes[2][0] = -m_clipPlanes[2][0];
|
||||
m_clipPlanes[2][1] = -m_clipPlanes[2][1];
|
||||
m_clipPlanes[2][2] = -m_clipPlanes[2][2];
|
||||
}
|
||||
}
|
||||
|
||||
/* Top */
|
||||
m_clipPlanes[3][3] = 0.00000001;
|
||||
if (cy == 0) m_clipPlanes[3][1] = 1.0;
|
||||
else
|
||||
{
|
||||
_FindNormal(100, -100,
|
||||
100, 100,
|
||||
m_fovfactor*m_adj_asp*-100.0/(cy),
|
||||
m_clipPlanes[3]);
|
||||
if (cy < 0)
|
||||
{
|
||||
m_clipPlanes[3][0] = -m_clipPlanes[3][0];
|
||||
m_clipPlanes[3][1] = -m_clipPlanes[3][1];
|
||||
m_clipPlanes[3][2] = -m_clipPlanes[3][2];
|
||||
}
|
||||
}
|
||||
|
||||
/* Bottom */
|
||||
m_clipPlanes[4][3] = 0.00000001;
|
||||
if (cy == fbh) m_clipPlanes[4][1] = -1.0;
|
||||
else
|
||||
{
|
||||
_FindNormal(-100, 100,
|
||||
-100, -100,
|
||||
m_fovfactor*m_adj_asp*100.0/(cy-fbh),
|
||||
m_clipPlanes[4]);
|
||||
if (cy > fbh)
|
||||
{
|
||||
m_clipPlanes[4][0] = -m_clipPlanes[4][0];
|
||||
m_clipPlanes[4][1] = -m_clipPlanes[4][1];
|
||||
m_clipPlanes[4][2] = -m_clipPlanes[4][2];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Returns: 0 if nothing gets in, 1 or 2 if pout1 & pout2 get in */
|
||||
pl_uInt pl_Cam::_ClipToPlane(pl_uInt numVerts, pl_Float *plane)
|
||||
{
|
||||
pl_uInt i, nextvert, curin, nextin;
|
||||
double curdot, nextdot, scale;
|
||||
pl_uInt invert, outvert;
|
||||
invert = 0;
|
||||
outvert = 0;
|
||||
curdot = m_cl[0].newVertices[0].xformedx*plane[0] +
|
||||
m_cl[0].newVertices[0].xformedy*plane[1] +
|
||||
m_cl[0].newVertices[0].xformedz*plane[2];
|
||||
curin = (curdot >= plane[3]);
|
||||
|
||||
for (i=0 ; i < numVerts; i++) {
|
||||
nextvert = (i + 1) % numVerts;
|
||||
if (curin) {
|
||||
memcpy(&m_cl[1].ShadeInfos[outvert][0],&m_cl[0].ShadeInfos[invert][0],3*sizeof(pl_Float));
|
||||
int a;
|
||||
for(a=0;a<PLUSH_MAX_MAPCOORDS;a++)
|
||||
{
|
||||
m_cl[1].MappingU[a][outvert] = m_cl[0].MappingU[a][invert];
|
||||
m_cl[1].MappingV[a][outvert] = m_cl[0].MappingV[a][invert];
|
||||
}
|
||||
m_cl[1].newVertices[outvert++] = m_cl[0].newVertices[invert];
|
||||
}
|
||||
nextdot = m_cl[0].newVertices[nextvert].xformedx*plane[0] +
|
||||
m_cl[0].newVertices[nextvert].xformedy*plane[1] +
|
||||
m_cl[0].newVertices[nextvert].xformedz*plane[2];
|
||||
nextin = (nextdot >= plane[3]);
|
||||
if (curin != nextin) {
|
||||
scale = (plane[3] - curdot) / (nextdot - curdot);
|
||||
m_cl[1].newVertices[outvert].xformedx = (pl_Float) (m_cl[0].newVertices[invert].xformedx +
|
||||
(m_cl[0].newVertices[nextvert].xformedx - m_cl[0].newVertices[invert].xformedx)
|
||||
* scale);
|
||||
m_cl[1].newVertices[outvert].xformedy = (pl_Float) (m_cl[0].newVertices[invert].xformedy +
|
||||
(m_cl[0].newVertices[nextvert].xformedy - m_cl[0].newVertices[invert].xformedy)
|
||||
* scale);
|
||||
m_cl[1].newVertices[outvert].xformedz = (pl_Float) (m_cl[0].newVertices[invert].xformedz +
|
||||
(m_cl[0].newVertices[nextvert].xformedz - m_cl[0].newVertices[invert].xformedz)
|
||||
* scale);
|
||||
|
||||
m_cl[1].ShadeInfos[outvert][0] = m_cl[0].ShadeInfos[invert][0] + (m_cl[0].ShadeInfos[nextvert][0] - m_cl[0].ShadeInfos[invert][0]) * scale;
|
||||
m_cl[1].ShadeInfos[outvert][1] = m_cl[0].ShadeInfos[invert][1] + (m_cl[0].ShadeInfos[nextvert][1] - m_cl[0].ShadeInfos[invert][1]) * scale;
|
||||
m_cl[1].ShadeInfos[outvert][2] = m_cl[0].ShadeInfos[invert][2] + (m_cl[0].ShadeInfos[nextvert][2] - m_cl[0].ShadeInfos[invert][2]) * scale;
|
||||
|
||||
int a;
|
||||
for(a=0;a<PLUSH_MAX_MAPCOORDS;a++)
|
||||
{
|
||||
m_cl[1].MappingU[a][outvert] = m_cl[0].MappingU[a][invert] +
|
||||
(m_cl[0].MappingU[a][nextvert] - m_cl[0].MappingU[a][invert]) * scale;
|
||||
m_cl[1].MappingV[a][outvert] = m_cl[0].MappingV[a][invert] +
|
||||
(m_cl[0].MappingV[a][nextvert] - m_cl[0].MappingV[a][invert]) * scale;
|
||||
}
|
||||
outvert++;
|
||||
}
|
||||
curdot = nextdot;
|
||||
curin = nextin;
|
||||
invert++;
|
||||
}
|
||||
return outvert;
|
||||
}
|
||||
|
||||
bool pl_Cam::ProjectCoordinate(pl_Float x, pl_Float y, pl_Float z, pl_Float *screen_x, pl_Float *screen_y, pl_Float *dist)
|
||||
{
|
||||
x -= X;
|
||||
y -= Y;
|
||||
z -= Z;
|
||||
plMatrixApply(CamMatrix,x,y,z,&x,&y,&z);
|
||||
|
||||
if (dist) *dist = sqrt(x*x + y*y + z*z);
|
||||
|
||||
if (!m_lastFBWidth || !m_lastFBHeight || z < 0.0000000001) return false;
|
||||
|
||||
const double iz = 1.0/z;
|
||||
double ytmp = CalcFOVFactor(m_lastFBWidth) * iz;
|
||||
double xtmp = ytmp*x;
|
||||
ytmp *= y*m_adj_asp;
|
||||
|
||||
xtmp += CenterX + m_lastFBWidth/2;
|
||||
ytmp += CenterY + m_lastFBHeight/2;
|
||||
|
||||
if (screen_x) *screen_x = xtmp;
|
||||
if (screen_y) *screen_y = ytmp;
|
||||
|
||||
return xtmp >= 0 && xtmp < m_lastFBWidth && ytmp >= 0 && ytmp < m_lastFBHeight;
|
||||
}
|
||||
|
||||
|
||||
void pl_Cam::ClipRenderFace(pl_Face *face, pl_Obj *obj) {
|
||||
const int cx = m_lastCX, cy = m_lastCY;
|
||||
|
||||
{
|
||||
pl_Vertex *vlist=obj->Vertices.Get();
|
||||
int a;
|
||||
for (a = 0; a < 3; a ++) {
|
||||
m_cl[0].newVertices[a] = vlist[face->VertexIndices[a]];
|
||||
|
||||
memcpy(&m_cl[0].ShadeInfos[a][0],&face->Shades[a][0],3*sizeof(pl_Float));
|
||||
int b;
|
||||
for(b=0;b<PLUSH_MAX_MAPCOORDS;b++)
|
||||
{
|
||||
m_cl[0].MappingU[b][a] = face->MappingU[b][a];
|
||||
m_cl[0].MappingV[b][a] = face->MappingV[b][a];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pl_uInt numVerts = 3;
|
||||
{
|
||||
int a = (m_clipPlanes[0][3] < 0.0 ? 0 : 1);
|
||||
while (a < PL_NUM_CLIP_PLANES && numVerts > 2)
|
||||
{
|
||||
numVerts = _ClipToPlane(numVerts, m_clipPlanes[a]);
|
||||
memcpy(&m_cl[0],&m_cl[1],sizeof(m_cl[0]));
|
||||
a++;
|
||||
}
|
||||
}
|
||||
if (numVerts > 2) {
|
||||
pl_Face newface;
|
||||
memcpy(&newface,face,sizeof(pl_Face));
|
||||
int k;
|
||||
for (k = 2; k < (int)numVerts; k ++) {
|
||||
int a;
|
||||
for (a = 0; a < 3; a ++) {
|
||||
int w;
|
||||
if (a == 0) w = 0;
|
||||
else w = a+(k-2); ;
|
||||
pl_Vertex *thisv=m_cl[0].newVertices+w;
|
||||
newface.Shades[a][0] = m_cl[0].ShadeInfos[w][0];
|
||||
newface.Shades[a][1] = m_cl[0].ShadeInfos[w][1];
|
||||
newface.Shades[a][2] = m_cl[0].ShadeInfos[w][2];
|
||||
int b;
|
||||
for(b=0;b<PLUSH_MAX_MAPCOORDS;b++)
|
||||
{
|
||||
newface.MappingU[b][a] = m_cl[0].MappingU[b][w];
|
||||
newface.MappingV[b][a] = m_cl[0].MappingV[b][w];
|
||||
}
|
||||
newface.Scrz[a] = 1.0f/thisv->xformedz;
|
||||
double ytmp = m_fovfactor * newface.Scrz[a];
|
||||
double xtmp = ytmp*thisv->xformedx;
|
||||
ytmp *= thisv->xformedy*m_adj_asp;
|
||||
newface.Scrx[a] = xtmp+cx;
|
||||
newface.Scry[a] = ytmp+cy;
|
||||
}
|
||||
RenderTrisOut++;
|
||||
|
||||
// quick approx of triangle area
|
||||
RenderPixelsOut += 0.5*fabs(
|
||||
(newface.Scrx[1] - newface.Scrx[0]) *
|
||||
(newface.Scry[2] - newface.Scry[0]) -
|
||||
(newface.Scrx[2] - newface.Scrx[0]) *
|
||||
(newface.Scry[1] - newface.Scry[0]) );
|
||||
|
||||
PutFace(&newface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pl_sInt pl_Cam::ClipNeeded(pl_Face *face, pl_Obj *obj) {
|
||||
const int fbw=m_fBuffer.m_w, fbh=m_fBuffer.m_h;
|
||||
const int cx = m_lastCX, cy = m_lastCY;
|
||||
double dr,dl,db,dt;
|
||||
double f;
|
||||
dr = (fbw-cx);
|
||||
dl = (-cx);
|
||||
db = (fbh-cy);
|
||||
dt = (-cy);
|
||||
f = m_fovfactor*m_adj_asp;
|
||||
pl_Vertex *vlist=obj->Vertices.Get();
|
||||
pl_Vertex *v0=vlist+face->VertexIndices[0];
|
||||
pl_Vertex *v1=vlist+face->VertexIndices[1];
|
||||
pl_Vertex *v2=vlist+face->VertexIndices[2];
|
||||
|
||||
return ((ClipBack <= 0.0 ||
|
||||
v0->xformedz <= ClipBack ||
|
||||
v1->xformedz <= ClipBack ||
|
||||
v2->xformedz <= ClipBack) &&
|
||||
(v0->xformedz >= 0 ||
|
||||
v1->xformedz >= 0 ||
|
||||
v2->xformedz >= 0) &&
|
||||
(v0->xformedx*m_fovfactor<=dr*v0->xformedz ||
|
||||
v1->xformedx*m_fovfactor<=dr*v1->xformedz ||
|
||||
v2->xformedx*m_fovfactor<=dr*v2->xformedz) &&
|
||||
(v0->xformedx*m_fovfactor>=dl*v0->xformedz ||
|
||||
v1->xformedx*m_fovfactor>=dl*v1->xformedz ||
|
||||
v2->xformedx*m_fovfactor>=dl*v2->xformedz) &&
|
||||
(v0->xformedy*f<=db*v0->xformedz ||
|
||||
v1->xformedy*f<=db*v1->xformedz ||
|
||||
v2->xformedy*f<=db*v2->xformedz) &&
|
||||
(v0->xformedy*f>=dt*v0->xformedz ||
|
||||
v1->xformedy*f>=dt*v1->xformedz ||
|
||||
v2->xformedy*f>=dt*v2->xformedz));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void pl_Cam::Begin(LICE_IBitmap *fb, bool want_zbclear, pl_ZBuffer zbclear) {
|
||||
if (WDL_NOT_NORMALLY(m_fBuffer.m_buf) || WDL_NOT_NORMALLY(!fb)) return;
|
||||
|
||||
m_lastFBWidth=fb->getWidth();
|
||||
m_lastFBHeight=fb->getHeight();
|
||||
m_lastFBScaling = (int)fb->Extended(LICE_EXT_GET_SCALING,NULL);
|
||||
if (m_lastFBScaling==0 || WDL_NOT_NORMALLY(m_lastFBScaling > 1024)) m_lastFBScaling=256;
|
||||
|
||||
m_fBuffer.m_buf = fb->getBits();
|
||||
m_fBuffer.m_span = fb->getRowSpan();
|
||||
m_fBuffer.m_w = fb->getWidth() * m_lastFBScaling / 256;
|
||||
m_fBuffer.m_h = fb->getHeight() * m_lastFBScaling / 256;
|
||||
m_fBuffer.m_flipped = fb->isFlipped();
|
||||
|
||||
if (WantZBuffer)
|
||||
{
|
||||
int zbsz=m_fBuffer.m_w*m_fBuffer.m_h;
|
||||
pl_ZBuffer *zb=zBuffer.ResizeOK(zbsz);
|
||||
if (!zb) zBuffer.Resize(0);
|
||||
else if (want_zbclear)
|
||||
{
|
||||
if (!zbclear) memset(zb,0,zbsz*sizeof(pl_ZBuffer));
|
||||
else
|
||||
{
|
||||
int i=zbsz;
|
||||
while(i--) *zb++=zbclear;
|
||||
}
|
||||
}
|
||||
}
|
||||
else zBuffer.Resize(0);
|
||||
pl_Float tempMatrix[16];
|
||||
_numlights = 0;
|
||||
_numfaces = _numfaces_sorted = 0;
|
||||
if (GenMatrix)
|
||||
{
|
||||
plMatrixRotate(CamMatrix,2,-Pan);
|
||||
plMatrixRotate(tempMatrix,1,-Pitch);
|
||||
plMatrixMultiply(CamMatrix,tempMatrix);
|
||||
plMatrixRotate(tempMatrix,3,-Roll);
|
||||
plMatrixMultiply(CamMatrix,tempMatrix);
|
||||
}
|
||||
|
||||
RecalcFrustum(m_fBuffer.m_w, m_fBuffer.m_h);
|
||||
|
||||
RenderTrisIn=RenderTrisCulled=RenderTrisOut=0;
|
||||
RenderPixelsOut=0.0;
|
||||
|
||||
}
|
||||
|
||||
void pl_Cam::RenderLight(pl_Light *light) {
|
||||
if (!light||WDL_NOT_NORMALLY(!m_fBuffer.m_buf)) return;
|
||||
|
||||
pl_Float *pl, xp, yp, zp;
|
||||
if (light->Type == PL_LIGHT_NONE) return;
|
||||
if (_lights.GetSize()<=_numlights) _lights.Resize(_numlights+1);
|
||||
pl = _lights.Get()[_numlights].l;
|
||||
if (light->Type == PL_LIGHT_VECTOR) {
|
||||
xp = light->Xp;
|
||||
yp = light->Yp;
|
||||
zp = light->Zp;
|
||||
MACRO_plMatrixApply(CamMatrix,xp,yp,zp,pl[0],pl[1],pl[2]);
|
||||
} else if (light->Type & PL_LIGHT_POINT) {
|
||||
xp = light->Xp-X;
|
||||
yp = light->Yp-Y;
|
||||
zp = light->Zp-Z;
|
||||
MACRO_plMatrixApply(CamMatrix,xp,yp,zp,pl[0],pl[1],pl[2]);
|
||||
}
|
||||
_lights.Get()[_numlights++].light = light;
|
||||
}
|
||||
|
||||
void pl_Cam::RenderObject(pl_Obj *obj, const pl_Float *bmatrix, const pl_Float *bnmatrix) {
|
||||
if (!obj||WDL_NOT_NORMALLY(!m_fBuffer.m_buf)) return;
|
||||
|
||||
pl_Float oMatrix[16], nMatrix[16], tempMatrix[16];
|
||||
|
||||
if (obj->GenMatrix) {
|
||||
plMatrixRotate(nMatrix,1,obj->Xa);
|
||||
plMatrixRotate(tempMatrix,2,obj->Ya);
|
||||
plMatrixMultiply(nMatrix,tempMatrix);
|
||||
plMatrixRotate(tempMatrix,3,obj->Za);
|
||||
plMatrixMultiply(nMatrix,tempMatrix);
|
||||
memcpy(obj->RotMatrix,nMatrix,sizeof(pl_Float)*16);
|
||||
|
||||
memcpy(oMatrix,nMatrix,sizeof(pl_Float)*16);
|
||||
plMatrixTranslate(tempMatrix, obj->Xp, obj->Yp, obj->Zp);
|
||||
plMatrixMultiply(oMatrix,tempMatrix);
|
||||
memcpy(obj->Matrix,oMatrix,sizeof(pl_Float)*16);
|
||||
} else {
|
||||
memcpy(oMatrix,obj->Matrix,sizeof(pl_Float)*16);
|
||||
memcpy(nMatrix,obj->RotMatrix,sizeof(pl_Float)*16);
|
||||
}
|
||||
|
||||
if (bnmatrix) plMatrixMultiply(nMatrix,bnmatrix);
|
||||
if (bmatrix) plMatrixMultiply(oMatrix,bmatrix);
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < obj->Children.GetSize(); i ++)
|
||||
if (obj->Children.Get(i)) RenderObject(obj->Children.Get(i),oMatrix,nMatrix);
|
||||
}
|
||||
if (!obj->Faces.GetSize() || !obj->Vertices.GetSize()) return;
|
||||
|
||||
plMatrixTranslate(tempMatrix, -X, -Y, -Z);
|
||||
plMatrixMultiply(oMatrix,tempMatrix);
|
||||
plMatrixMultiply(oMatrix,CamMatrix);
|
||||
plMatrixMultiply(nMatrix,CamMatrix);
|
||||
|
||||
{
|
||||
pl_Vertex *vertex = obj->Vertices.Get();
|
||||
int i = obj->Vertices.GetSize();
|
||||
|
||||
while (i--)
|
||||
{
|
||||
MACRO_plMatrixApply(oMatrix,vertex->x,vertex->y,vertex->z,
|
||||
vertex->xformedx, vertex->xformedy, vertex->xformedz);
|
||||
MACRO_plMatrixApply(nMatrix,vertex->nx,vertex->ny,vertex->nz,
|
||||
vertex->xformednx,vertex->xformedny,vertex->xformednz);
|
||||
vertex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (_faces.GetSize() < _numfaces + obj->Faces.GetSize()) _faces.Resize(_numfaces + obj->Faces.GetSize());
|
||||
|
||||
|
||||
_faceInfo *facelistout = _faces.Get() + _numfaces;
|
||||
|
||||
pl_Face *face = obj->Faces.Get();
|
||||
int facecnt = obj->Faces.GetSize();
|
||||
|
||||
RenderTrisIn += facecnt;
|
||||
_numfaces += facecnt;
|
||||
pl_Vertex *vlist = obj->Vertices.Get();
|
||||
|
||||
while (facecnt--)
|
||||
{
|
||||
double nx,ny,nz;
|
||||
pl_Mat *mat=face->Material;
|
||||
if (mat->BackfaceCull || (mat->Lightable && !mat->Smoothing))
|
||||
{
|
||||
MACRO_plMatrixApply(nMatrix,face->nx,face->ny,face->nz,nx,ny,nz);
|
||||
}
|
||||
pl_Vertex *v0=vlist+face->VertexIndices[0];
|
||||
pl_Vertex *v1=vlist+face->VertexIndices[1];
|
||||
pl_Vertex *v2=vlist+face->VertexIndices[2];
|
||||
|
||||
if (!mat->BackfaceCull || (MACRO_plDotProduct(nx,ny,nz, v0->xformedx, v0->xformedy, v0->xformedz) < 0.0000001)) {
|
||||
if (ClipNeeded(face,obj)) {
|
||||
if (!mat->Smoothing && (mat->Lightable||mat->FadeDist)) {
|
||||
pl_Float val[3];
|
||||
memcpy(val,face->sLighting,3*sizeof(pl_Float));
|
||||
if (mat->Lightable) {
|
||||
_lightInfo *inf = _lights.Get();
|
||||
int i=_numlights;
|
||||
while (i--)
|
||||
{
|
||||
pl_Light *light = inf->light;
|
||||
double lightsc=0.0;
|
||||
if (light->Type & PL_LIGHT_POINT_ANGLE) {
|
||||
double nx2 = inf->l[0] - v0->xformedx;
|
||||
double ny2 = inf->l[1] - v0->xformedy;
|
||||
double nz2 = inf->l[2] - v0->xformedz;
|
||||
MACRO_plNormalizeVector(nx2,ny2,nz2);
|
||||
lightsc = MACRO_plDotProduct(nx,ny,nz,nx2,ny2,nz2);
|
||||
}
|
||||
if (light->Type & PL_LIGHT_POINT_DISTANCE) {
|
||||
double nx2 = inf->l[0] - v0->xformedx;
|
||||
double ny2 = inf->l[1] - v0->xformedy;
|
||||
double nz2 = inf->l[2] - v0->xformedz;
|
||||
if (light->Type & PL_LIGHT_POINT_ANGLE) {
|
||||
nx2 = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/
|
||||
light->HalfDistSquared));
|
||||
lightsc *= plMax(0,plMin(1.0,nx2));
|
||||
} else {
|
||||
lightsc = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/
|
||||
light->HalfDistSquared));
|
||||
lightsc = plMax(0,plMin(1.0,lightsc));
|
||||
}
|
||||
}
|
||||
if (light->Type == PL_LIGHT_VECTOR)
|
||||
lightsc = MACRO_plDotProduct(nx,ny,nz,inf->l[0],inf->l[1],inf->l[2]);
|
||||
|
||||
if (lightsc>0.0)
|
||||
{
|
||||
val[0] += light->Intensity[0]*lightsc;
|
||||
val[1] += light->Intensity[1]*lightsc;
|
||||
val[2] += light->Intensity[2]*lightsc;
|
||||
}
|
||||
else if (mat->BackfaceIllumination)
|
||||
{
|
||||
val[0] -= light->Intensity[0]*lightsc*mat->BackfaceIllumination;
|
||||
val[1] -= light->Intensity[1]*lightsc*mat->BackfaceIllumination;
|
||||
val[2] -= light->Intensity[2]*lightsc*mat->BackfaceIllumination;
|
||||
}
|
||||
inf++;
|
||||
} /* End of light loop */
|
||||
} /* End of flat shading if */
|
||||
|
||||
if (mat->FadeDist)
|
||||
{
|
||||
double lightsc = 1.0 - (v0->xformedz+v1->xformedz+v2->xformedz) / (mat->FadeDist*3.0);
|
||||
if (lightsc<0.0) lightsc=0.0;
|
||||
else if (lightsc>1.0)lightsc=1.0;
|
||||
if (mat->Lightable)
|
||||
{
|
||||
val[0] *= lightsc;
|
||||
val[1] *= lightsc;
|
||||
val[2] *= lightsc;
|
||||
}
|
||||
else
|
||||
{
|
||||
val[0]+=lightsc;
|
||||
val[1]+=lightsc;
|
||||
val[2]+=lightsc;
|
||||
}
|
||||
}
|
||||
face->Shades[0][0]=mat->Ambient[0] + mat->Diffuse[0]*val[0];
|
||||
face->Shades[0][1]=mat->Ambient[1] + mat->Diffuse[1]*val[1];
|
||||
face->Shades[0][2]=mat->Ambient[2] + mat->Diffuse[2]*val[2];
|
||||
}
|
||||
else memcpy(face->Shades,mat->Ambient,sizeof(mat->Ambient)); // flat shading
|
||||
|
||||
if ((mat->Texture && mat->TexMapIdx<0)||(mat->Texture2 && mat->Tex2MapIdx<0)) {
|
||||
face->MappingU[PLUSH_MAX_MAPCOORDS-1][0] = 0.5 + (v0->xformednx);
|
||||
face->MappingV[PLUSH_MAX_MAPCOORDS-1][0] = 0.5 - (v0->xformedny);
|
||||
face->MappingU[PLUSH_MAX_MAPCOORDS-1][1] = 0.5 + (v1->xformednx);
|
||||
face->MappingV[PLUSH_MAX_MAPCOORDS-1][1] = 0.5 - (v1->xformedny);
|
||||
face->MappingU[PLUSH_MAX_MAPCOORDS-1][2] = 0.5 + (v2->xformednx);
|
||||
face->MappingV[PLUSH_MAX_MAPCOORDS-1][2] = 0.5 - (v2->xformedny);
|
||||
}
|
||||
|
||||
if (mat->Smoothing && (mat->Lightable || mat->FadeDist))
|
||||
{
|
||||
int a;
|
||||
for (a = 0; a < 3; a ++) {
|
||||
pl_Float val[3];
|
||||
memcpy(val,face->vsLighting[a],sizeof(val));
|
||||
pl_Vertex *thisvert = obj->Vertices.Get()+face->VertexIndices[a];
|
||||
|
||||
if (mat->Lightable)
|
||||
{
|
||||
int i=_numlights;
|
||||
_lightInfo *inf = _lights.Get();
|
||||
while (i--)
|
||||
{
|
||||
double lightsc = 0.0;
|
||||
pl_Light *light = inf->light;
|
||||
if (light->Type & PL_LIGHT_POINT_ANGLE) {
|
||||
double nx2 = inf->l[0] - thisvert->xformedx;
|
||||
double ny2 = inf->l[1] - thisvert->xformedy;
|
||||
double nz2 = inf->l[2] - thisvert->xformedz;
|
||||
MACRO_plNormalizeVector(nx2,ny2,nz2);
|
||||
lightsc = MACRO_plDotProduct(thisvert->xformednx,
|
||||
thisvert->xformedny,
|
||||
thisvert->xformednz,
|
||||
nx2,ny2,nz2);
|
||||
}
|
||||
if (light->Type & PL_LIGHT_POINT_DISTANCE) {
|
||||
double nx2 = inf->l[0] - thisvert->xformedx;
|
||||
double ny2 = inf->l[1] - thisvert->xformedy;
|
||||
double nz2 = inf->l[2] - thisvert->xformedz;
|
||||
if (light->Type & PL_LIGHT_POINT_ANGLE) {
|
||||
double t= (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/light->HalfDistSquared));
|
||||
lightsc *= plMax(0,plMin(1.0,t));
|
||||
} else {
|
||||
lightsc = (1.0 - 0.5*((nx2*nx2+ny2*ny2+nz2*nz2)/light->HalfDistSquared));
|
||||
lightsc = plMax(0,plMin(1.0,lightsc));
|
||||
}
|
||||
}
|
||||
|
||||
if (light->Type == PL_LIGHT_VECTOR)
|
||||
lightsc = MACRO_plDotProduct(thisvert->xformednx,
|
||||
thisvert->xformedny,
|
||||
thisvert->xformednz,
|
||||
inf->l[0],inf->l[1],inf->l[2]);
|
||||
if (lightsc > 0.0)
|
||||
{
|
||||
val[0] += lightsc * light->Intensity[0];
|
||||
val[1] += lightsc * light->Intensity[1];
|
||||
val[2] += lightsc * light->Intensity[2];
|
||||
}
|
||||
else if (mat->BackfaceIllumination)
|
||||
{
|
||||
val[0] -= lightsc * light->Intensity[0]*mat->BackfaceIllumination;
|
||||
val[1] -= lightsc * light->Intensity[1]*mat->BackfaceIllumination;
|
||||
val[2] -= lightsc * light->Intensity[2]*mat->BackfaceIllumination;
|
||||
}
|
||||
inf++;
|
||||
} /* End of light loop */
|
||||
} /* End of gouraud shading if */
|
||||
if (mat->FadeDist)
|
||||
{
|
||||
double lightsc = 1.0-thisvert->xformedz/mat->FadeDist;
|
||||
if (lightsc<0.0) lightsc=0.0;
|
||||
else if (lightsc>1.0)lightsc=1.0;
|
||||
if (mat->Lightable)
|
||||
{
|
||||
val[0] *= lightsc;
|
||||
val[1] *= lightsc;
|
||||
val[2] *= lightsc;
|
||||
}
|
||||
else
|
||||
{
|
||||
val[0] += lightsc;
|
||||
val[1] += lightsc;
|
||||
val[2] += lightsc;
|
||||
}
|
||||
}
|
||||
face->Shades[a][0] = mat->Ambient[0] + mat->Diffuse[0]*val[0];
|
||||
face->Shades[a][1] = mat->Ambient[1] + mat->Diffuse[1]*val[1];
|
||||
face->Shades[a][2] = mat->Ambient[2] + mat->Diffuse[2]*val[2];
|
||||
} /* End of vertex loop for */
|
||||
} /* End of gouraud shading mask if */
|
||||
else // flat modes, shade all vertices
|
||||
{
|
||||
memcpy(&face->Shades[1][0],&face->Shades[0][0],sizeof(pl_Float)*3);
|
||||
memcpy(&face->Shades[2][0],&face->Shades[0][0],sizeof(pl_Float)*3);
|
||||
}
|
||||
|
||||
facelistout->zd = v0->xformedz+v1->xformedz+v2->xformedz;
|
||||
facelistout->obj=obj;
|
||||
facelistout->face = face;
|
||||
facelistout++;
|
||||
|
||||
|
||||
RenderTrisCulled++;
|
||||
|
||||
} /* Is it in our area Check */
|
||||
} /* Backface Check */
|
||||
face++;
|
||||
}
|
||||
_numfaces = facelistout-_faces.Get();
|
||||
}
|
||||
void pl_Cam::SortToCurrent()
|
||||
{
|
||||
if (Sort && _numfaces > _numfaces_sorted+1)
|
||||
{
|
||||
WDL_mergesort(_faces.Get()+_numfaces_sorted,
|
||||
_numfaces-_numfaces_sorted,sizeof(_faceInfo),
|
||||
Sort > 0 ? sortFwdFunc : sortRevFunc,
|
||||
(char*)_sort_tmpspace.Resize((_numfaces-_numfaces_sorted)*sizeof(_faceInfo),false));
|
||||
}
|
||||
_numfaces_sorted=_numfaces;
|
||||
}
|
||||
|
||||
int pl_Cam::sortRevFunc(const void *a, const void *b)
|
||||
{
|
||||
_faceInfo *aa = (_faceInfo*)a;
|
||||
_faceInfo *bb = (_faceInfo*)b;
|
||||
|
||||
if (aa->zd < bb->zd) return -1;
|
||||
if (aa->zd > bb->zd) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pl_Cam::sortFwdFunc(const void *a, const void *b)
|
||||
{
|
||||
_faceInfo *aa = (_faceInfo*)a;
|
||||
_faceInfo *bb = (_faceInfo*)b;
|
||||
|
||||
if (aa->zd < bb->zd) return 1;
|
||||
if (aa->zd > bb->zd) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pl_Cam::End() {
|
||||
if (WDL_NOT_NORMALLY(!m_fBuffer.m_buf)) return;
|
||||
|
||||
SortToCurrent();
|
||||
|
||||
_faceInfo *f = _faces.Get();
|
||||
int n=_numfaces;
|
||||
while (n-->0)
|
||||
{
|
||||
if (f->face->Material)
|
||||
{
|
||||
ClipRenderFace(f->face,f->obj);
|
||||
}
|
||||
f++;
|
||||
}
|
||||
|
||||
m_fBuffer.m_buf = NULL;
|
||||
_numfaces=0;
|
||||
_numlights = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void pl_Light::Set(pl_uChar mode, pl_Float x, pl_Float y, pl_Float z, pl_Float intensity_r, pl_Float intensity_g, pl_Float intensity_b, pl_Float halfDist) {
|
||||
pl_Float m[16], m2[16];
|
||||
Type = mode;
|
||||
Intensity[0] = intensity_r;
|
||||
Intensity[1] = intensity_g;
|
||||
Intensity[2] = intensity_b;
|
||||
HalfDistSquared = halfDist*halfDist;
|
||||
switch (mode) {
|
||||
case PL_LIGHT_VECTOR:
|
||||
plMatrixRotate(m,1,x);
|
||||
plMatrixRotate(m2,2,y);
|
||||
plMatrixMultiply(m,m2);
|
||||
plMatrixRotate(m2,3,z);
|
||||
plMatrixMultiply(m,m2);
|
||||
plMatrixApply(m,0.0,0.0,-1.0,&Xp, &Yp, &Zp);
|
||||
break;
|
||||
case PL_LIGHT_POINT_ANGLE:
|
||||
case PL_LIGHT_POINT_DISTANCE:
|
||||
case PL_LIGHT_POINT:
|
||||
Xp = x;
|
||||
Yp = y;
|
||||
Zp = z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
537
oversampling/WDL/plush2/pl_make.cpp
Normal file
537
oversampling/WDL/plush2/pl_make.cpp
Normal file
@@ -0,0 +1,537 @@
|
||||
/******************************************************************************
|
||||
Plush Version 1.2
|
||||
make.c
|
||||
Object Primitives
|
||||
Copyright (c) 1996-2000, Justin Frankel
|
||||
*******************************************************************************
|
||||
Notes:
|
||||
Most of these routines are highly unoptimized.
|
||||
They could all use some work, such as more capable divisions (Box is
|
||||
most notable), etc... The mapping coordinates are all set up nicely,
|
||||
though.
|
||||
******************************************************************************/
|
||||
|
||||
#include "plush.h"
|
||||
|
||||
pl_Obj *plMakeTorus(pl_Float r1, pl_Float r2, pl_uInt divrot, pl_uInt divrad,
|
||||
pl_Mat *m) {
|
||||
pl_Obj *o;
|
||||
pl_Vertex *v;
|
||||
pl_Face *f;
|
||||
pl_uInt x, y;
|
||||
double ravg, rt, a, da, al, dal;
|
||||
pl_Float U,V,dU,dV;
|
||||
if (divrot < 3) divrot = 3;
|
||||
if (divrad < 3) divrad = 3;
|
||||
ravg = (r1+r2)*0.5;
|
||||
rt = (r2-r1)*0.5;
|
||||
o = new pl_Obj(divrad*divrot,divrad*divrot*2);
|
||||
if (!o) return 0;
|
||||
v = o->Vertices.Get();
|
||||
a = 0.0;
|
||||
da = 2*PL_PI/divrot;
|
||||
for (y = 0; y < divrot; y ++) {
|
||||
al = 0.0;
|
||||
dal = 2*PL_PI/divrad;
|
||||
for (x = 0; x < divrad; x ++) {
|
||||
v->x = (pl_Float) (cos((double) a)*(ravg + cos((double) al)*rt));
|
||||
v->z = (pl_Float) (sin((double) a)*(ravg + cos((double) al)*rt));
|
||||
v->y = (pl_Float) (sin((double) al)*rt);
|
||||
v++;
|
||||
al += dal;
|
||||
}
|
||||
a += da;
|
||||
}
|
||||
v = o->Vertices.Get();
|
||||
f = o->Faces.Get();
|
||||
dV = 1.0/divrad;
|
||||
dU = 1.0/divrot;
|
||||
U = 0;
|
||||
for (y = 0; y < divrot; y ++) {
|
||||
V = -0.5;
|
||||
for (x = 0; x < divrad; x ++) {
|
||||
f->VertexIndices[0] = v+x+y*divrad - o->Vertices.Get();
|
||||
f->MappingU[0][0] = U;
|
||||
f->MappingV[0][0] = V;
|
||||
f->VertexIndices[1] = v+(x+1==divrad?0:x+1)+y*divrad - o->Vertices.Get();
|
||||
f->MappingU[0][1] = U;
|
||||
f->MappingV[0][1] = V+dV;
|
||||
f->VertexIndices[2] = v+x+(y+1==divrot?0:(y+1)*divrad) - o->Vertices.Get();
|
||||
f->MappingU[0][2] = U+dU;
|
||||
f->MappingV[0][2] = V;
|
||||
f->Material = m;
|
||||
f++;
|
||||
f->VertexIndices[0] = v+x+(y+1==divrot?0:(y+1)*divrad) - o->Vertices.Get();
|
||||
f->MappingU[0][0] = U+dU;
|
||||
f->MappingV[0][0] = V;
|
||||
f->VertexIndices[1] = v+(x+1==divrad?0:x+1)+y*divrad - o->Vertices.Get();
|
||||
f->MappingU[0][1] = U;
|
||||
f->MappingV[0][1] = V+dV;
|
||||
f->VertexIndices[2] = v+(x+1==divrad?0:x+1)+(y+1==divrot?0:(y+1)*divrad) - o->Vertices.Get();
|
||||
f->MappingU[0][2] = U+dU;
|
||||
f->MappingV[0][2] = V+dV;
|
||||
f->Material = m;
|
||||
f++;
|
||||
V += dV;
|
||||
}
|
||||
U += dU;
|
||||
}
|
||||
o->CalculateNormals();
|
||||
return (o);
|
||||
}
|
||||
|
||||
pl_Obj *plMakeSphere(pl_Float r, pl_uInt divr, pl_uInt divh, pl_Mat *m) {
|
||||
pl_Obj *o;
|
||||
pl_Vertex *v;
|
||||
pl_Face *f;
|
||||
pl_uInt x, y;
|
||||
double a, da, yp, ya, yda, yf;
|
||||
pl_Float U,V,dU,dV;
|
||||
if (divh < 3) divh = 3;
|
||||
if (divr < 3) divr = 3;
|
||||
o = new pl_Obj(2+(divh-2)*(divr),2*divr+(divh-3)*divr*2);
|
||||
if (!o) return 0;
|
||||
v = o->Vertices.Get();
|
||||
v->x = v->z = 0.0; v->y = r; v++;
|
||||
v->x = v->z = 0.0; v->y = -r; v++;
|
||||
ya = 0.0;
|
||||
yda = PL_PI/(divh-1);
|
||||
da = (PL_PI*2.0)/divr;
|
||||
for (y = 0; y < divh - 2; y ++) {
|
||||
ya += yda;
|
||||
yp = cos((double) ya)*r;
|
||||
yf = sin((double) ya)*r;
|
||||
a = 0.0;
|
||||
for (x = 0; x < divr; x ++) {
|
||||
v->y = (pl_Float) yp;
|
||||
v->x = (pl_Float) (cos((double) a)*yf);
|
||||
v->z = (pl_Float) (sin((double) a)*yf);
|
||||
v++;
|
||||
a += da;
|
||||
}
|
||||
}
|
||||
f = o->Faces.Get();
|
||||
v = o->Vertices.Get() + 2;
|
||||
a = 0.0;
|
||||
U = 0;
|
||||
dU = 1.0/divr;
|
||||
dV = V = 1.0/divh;
|
||||
for (x = 0; x < divr; x ++) {
|
||||
f->VertexIndices[0] = 0;
|
||||
f->VertexIndices[1] = v + (x+1==divr ? 0 : x+1) - o->Vertices.Get();
|
||||
f->VertexIndices[2] = v + x - o->Vertices.Get();
|
||||
f->MappingU[0][0] = U;
|
||||
f->MappingV[0][0] = 0;
|
||||
f->MappingU[0][1] = U+dU;
|
||||
f->MappingV[0][1] = V;
|
||||
f->MappingU[0][2] = U;
|
||||
f->MappingV[0][2] = V;
|
||||
f->Material = m;
|
||||
f++;
|
||||
U += dU;
|
||||
}
|
||||
da = 1.0/(divr+1);
|
||||
v = o->Vertices.Get() + 2;
|
||||
for (x = 0; x < (divh-3); x ++) {
|
||||
U = 0;
|
||||
for (y = 0; y < divr; y ++) {
|
||||
f->VertexIndices[0] = v+y - o->Vertices.Get();
|
||||
f->VertexIndices[1] = v+divr+(y+1==divr?0:y+1) - o->Vertices.Get();
|
||||
f->VertexIndices[2] = v+y+divr - o->Vertices.Get();
|
||||
f->MappingU[0][0] = U;
|
||||
f->MappingV[0][0] = V;
|
||||
f->MappingU[0][1] = U+dU;
|
||||
f->MappingV[0][1] = V+dV;
|
||||
f->MappingU[0][2] = U;
|
||||
f->MappingV[0][2] = V+dV;
|
||||
f->Material = m; f++;
|
||||
f->VertexIndices[0] = v+y - o->Vertices.Get();
|
||||
f->VertexIndices[1] = v+(y+1==divr?0:y+1) - o->Vertices.Get();
|
||||
f->VertexIndices[2] = v+(y+1==divr?0:y+1)+divr - o->Vertices.Get();
|
||||
f->MappingU[0][0] = U;
|
||||
f->MappingV[0][0] = V;
|
||||
f->MappingU[0][1] = U+dU;
|
||||
f->MappingV[0][1] = V;
|
||||
f->MappingU[0][2] = U+dU;
|
||||
f->MappingV[0][2] = V+dV;
|
||||
f->Material = m; f++;
|
||||
U += dU;
|
||||
}
|
||||
V += dV;
|
||||
v += divr;
|
||||
}
|
||||
v = o->Vertices.Get() + o->Vertices.GetSize() - divr;
|
||||
U = 0;
|
||||
for (x = 0; x < divr; x ++) {
|
||||
f->VertexIndices[0] = 1;
|
||||
f->VertexIndices[1] = v + x - o->Vertices.Get();
|
||||
f->VertexIndices[2] = v + (x+1==divr ? 0 : x+1) - o->Vertices.Get();
|
||||
f->MappingU[0][0] = U;
|
||||
f->MappingV[0][0] = 1.0;
|
||||
f->MappingU[0][1] = U;
|
||||
f->MappingV[0][1] = V;
|
||||
f->MappingU[0][2] = U+dU;
|
||||
f->MappingV[0][2] = V;
|
||||
f->Material = m;
|
||||
f++;
|
||||
U += dU;
|
||||
}
|
||||
o->CalculateNormals();
|
||||
return (o);
|
||||
}
|
||||
|
||||
pl_Obj *plMakeDisc(pl_Float r, pl_uInt divr, pl_Mat *m)
|
||||
{
|
||||
pl_Obj *o;
|
||||
pl_Vertex *v;
|
||||
pl_Face *f;
|
||||
pl_uInt32 i;
|
||||
double a, da;
|
||||
|
||||
o=new pl_Obj(divr, divr);
|
||||
if (!o) return NULL;
|
||||
|
||||
a = 0.0;
|
||||
da = (2.0*PL_PI)/divr;
|
||||
v = o->Vertices.Get();
|
||||
for (i = 0; i < divr; i ++)
|
||||
{
|
||||
v->y = 0.0;
|
||||
v->x = (pl_Float) (r*cos((double) a));
|
||||
v->z = (pl_Float)(r*sin(a));
|
||||
v->xformedx = (0.5 + (0.5*cos((double) a))); // temp
|
||||
v->xformedy = (0.5 + (0.5*sin((double) a))); // use xf
|
||||
v++;
|
||||
a += da;
|
||||
}
|
||||
|
||||
v = o->Vertices.Get();
|
||||
f = o->Faces.Get();
|
||||
for (i = 0; i < divr; i ++)
|
||||
{
|
||||
f->VertexIndices[0] = i == divr-1 ? 0 : i + 1;
|
||||
f->VertexIndices[1] = i;
|
||||
f->VertexIndices[2] = 0;
|
||||
f->MappingU[0][0] = v[(i==divr-1?0:i+1)].xformedx;
|
||||
f->MappingV[0][0] = v[(i==divr-1?0:i+1)].xformedy;
|
||||
f->MappingU[0][1] = v[i].xformedx;
|
||||
f->MappingV[0][1] = v[i].xformedy;
|
||||
f->MappingU[0][2] = f->MappingV[0][2] = 0.5;
|
||||
f->Material = m;
|
||||
f++;
|
||||
}
|
||||
|
||||
f->VertexIndices[0] = 0;
|
||||
f->VertexIndices[1] = 2;
|
||||
f->VertexIndices[2] = 1;
|
||||
f->MappingU[0][0] = v[0].xformedx;
|
||||
f->MappingV[0][0] = v[0].xformedy;
|
||||
f->MappingU[0][1] = v[1].xformedx;
|
||||
f->MappingV[0][1] = v[1].xformedy;
|
||||
f->MappingU[0][2] = v[2].xformedx;
|
||||
f->MappingV[0][2] = v[2].xformedy;
|
||||
|
||||
f->Material = m;
|
||||
|
||||
o->CalculateNormals();
|
||||
return o;
|
||||
}
|
||||
|
||||
pl_Obj *plMakeCylinder(pl_Float r, pl_Float h, pl_uInt divr, pl_Bool captop,
|
||||
pl_Bool capbottom, pl_Mat *m) {
|
||||
pl_Obj *o;
|
||||
pl_Vertex *v, *topverts, *bottomverts, *topcapvert=0, *bottomcapvert=0;
|
||||
pl_Face *f;
|
||||
pl_uInt32 i;
|
||||
double a, da;
|
||||
if (divr < 3) divr = 3;
|
||||
o = new pl_Obj(divr*2+((divr==3)?0:(captop?1:0)+(capbottom?1:0)),
|
||||
divr*2+(divr==3 ? (captop ? 1 : 0) + (capbottom ? 1 : 0) :
|
||||
(captop ? divr : 0) + (capbottom ? divr : 0)));
|
||||
if (!o) return 0;
|
||||
a = 0.0;
|
||||
da = (2.0*PL_PI)/divr;
|
||||
v = o->Vertices.Get();
|
||||
topverts = v;
|
||||
for (i = 0; i < divr; i ++) {
|
||||
v->y = h/2.0f;
|
||||
v->x = (pl_Float) (r*cos((double) a));
|
||||
v->z = (pl_Float)(r*sin(a));
|
||||
v->xformedx = (0.5 + (0.5*cos((double) a))); // temp
|
||||
v->xformedy = (0.5 + (0.5*sin((double) a))); // use xf
|
||||
v++;
|
||||
a += da;
|
||||
}
|
||||
bottomverts = v;
|
||||
a = 0.0;
|
||||
for (i = 0; i < divr; i ++) {
|
||||
v->y = -h/2.0f;
|
||||
v->x = (pl_Float) (r*cos((double) a));
|
||||
v->z = (pl_Float) (r*sin(a));
|
||||
v->xformedx = (0.5 + (0.5*cos((double) a)));
|
||||
v->xformedy = (0.5 + (0.5*sin((double) a)));
|
||||
v++; a += da;
|
||||
}
|
||||
if (captop && divr != 3) {
|
||||
topcapvert = v;
|
||||
v->y = h / 2.0f;
|
||||
v->x = v->z = 0.0f;
|
||||
v++;
|
||||
}
|
||||
if (capbottom && divr != 3) {
|
||||
bottomcapvert = v;
|
||||
v->y = -h / 2.0f;
|
||||
v->x = v->z = 0.0f;
|
||||
v++;
|
||||
}
|
||||
f = o->Faces.Get();
|
||||
for (i = 0; i < divr; i ++) {
|
||||
f->VertexIndices[0] = bottomverts + i - o->Vertices.Get();
|
||||
f->VertexIndices[1] = topverts + i - o->Vertices.Get();
|
||||
f->VertexIndices[2] = bottomverts + (i == divr-1 ? 0 : i+1) - o->Vertices.Get();
|
||||
f->MappingV[0][0] = f->MappingV[0][2] = 1.0; f->MappingV[0][1] = 0;
|
||||
f->MappingU[0][0] = f->MappingU[0][1] = i/(double)divr;
|
||||
f->MappingU[0][2] = ((i+1))/(double)divr;
|
||||
f->Material = m; f++;
|
||||
f->VertexIndices[0] = bottomverts + (i == divr-1 ? 0 : i+1) - o->Vertices.Get();
|
||||
f->VertexIndices[1] = topverts + i - o->Vertices.Get();
|
||||
f->VertexIndices[2] = topverts + (i == divr-1 ? 0 : i+1) - o->Vertices.Get();
|
||||
f->MappingV[0][1] = f->MappingV[0][2] = 0; f->MappingV[0][0] = 1.0;
|
||||
f->MappingU[0][0] = f->MappingU[0][2] = ((i+1))/(double)divr;
|
||||
f->MappingU[0][1] = (i)/(double)divr;
|
||||
f->Material = m; f++;
|
||||
}
|
||||
if (captop) {
|
||||
if (divr == 3) {
|
||||
f->VertexIndices[0] = topverts + 0 - o->Vertices.Get();
|
||||
f->VertexIndices[1] = topverts + 2 - o->Vertices.Get();
|
||||
f->VertexIndices[2] = topverts + 1 - o->Vertices.Get();
|
||||
f->MappingU[0][0] = topverts[0].xformedx;
|
||||
f->MappingV[0][0] = topverts[0].xformedy;
|
||||
f->MappingU[0][1] = topverts[1].xformedx;
|
||||
f->MappingV[0][1] = topverts[1].xformedy;
|
||||
f->MappingU[0][2] = topverts[2].xformedx;
|
||||
f->MappingV[0][2] = topverts[2].xformedy;
|
||||
f->Material = m; f++;
|
||||
} else {
|
||||
for (i = 0; i < divr; i ++) {
|
||||
f->VertexIndices[0] = topverts + (i == divr-1 ? 0 : i + 1) - o->Vertices.Get();
|
||||
f->VertexIndices[1] = topverts + i - o->Vertices.Get();
|
||||
f->VertexIndices[2] = topcapvert - o->Vertices.Get();
|
||||
f->MappingU[0][0] = topverts[(i==divr-1?0:i+1)].xformedx;
|
||||
f->MappingV[0][0] = topverts[(i==divr-1?0:i+1)].xformedy;
|
||||
f->MappingU[0][1] = topverts[i].xformedx;
|
||||
f->MappingV[0][1] = topverts[i].xformedy;
|
||||
f->MappingU[0][2] = f->MappingV[0][2] = 0.5;
|
||||
f->Material = m; f++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (capbottom) {
|
||||
if (divr == 3) {
|
||||
f->VertexIndices[0] = bottomverts + 0 - o->Vertices.Get();
|
||||
f->VertexIndices[1] = bottomverts + 1 - o->Vertices.Get();
|
||||
f->VertexIndices[2] = bottomverts + 2 - o->Vertices.Get();
|
||||
f->MappingU[0][0] = bottomverts[0].xformedx;
|
||||
f->MappingV[0][0] = bottomverts[0].xformedy;
|
||||
f->MappingU[0][1] = bottomverts[1].xformedx;
|
||||
f->MappingV[0][1] = bottomverts[1].xformedy;
|
||||
f->MappingU[0][2] = bottomverts[2].xformedx;
|
||||
f->MappingV[0][2] = bottomverts[2].xformedy;
|
||||
f->Material = m; f++;
|
||||
} else {
|
||||
for (i = 0; i < divr; i ++) {
|
||||
f->VertexIndices[0] = bottomverts + i - o->Vertices.Get();
|
||||
f->VertexIndices[1] = bottomverts + (i == divr-1 ? 0 : i + 1) - o->Vertices.Get();
|
||||
f->VertexIndices[2] = bottomcapvert - o->Vertices.Get();
|
||||
f->MappingU[0][0] = bottomverts[i].xformedx;
|
||||
f->MappingV[0][0] = bottomverts[i].xformedy;
|
||||
f->MappingU[0][1] = bottomverts[(i==divr-1?0:i+1)].xformedx;
|
||||
f->MappingV[0][1] = bottomverts[(i==divr-1?0:i+1)].xformedy;
|
||||
f->MappingU[0][2] = f->MappingV[0][2] = 0.5;
|
||||
f->Material = m; f++;
|
||||
}
|
||||
}
|
||||
}
|
||||
o->CalculateNormals();
|
||||
return (o);
|
||||
}
|
||||
|
||||
pl_Obj *plMakeCone(pl_Float r, pl_Float h, pl_uInt div,
|
||||
pl_Bool cap, pl_Mat *m) {
|
||||
pl_Obj *o;
|
||||
pl_Vertex *v;
|
||||
pl_Face *f;
|
||||
pl_uInt32 i;
|
||||
double a, da;
|
||||
if (div < 3) div = 3;
|
||||
o = new pl_Obj(div + (div == 3 ? 1 : (cap ? 2 : 1)),
|
||||
div + (div == 3 ? 1 : (cap ? div : 0)));
|
||||
if (!o) return 0;
|
||||
v = o->Vertices.Get();
|
||||
v->x = v->z = 0; v->y = h/2;
|
||||
v->xformedx = 0.5;
|
||||
v->xformedy = 0.5;
|
||||
v++;
|
||||
a = 0.0;
|
||||
da = (2.0*PL_PI)/div;
|
||||
for (i = 1; i <= div; i ++) {
|
||||
v->y = h/-2.0f;
|
||||
v->x = (pl_Float) (r*cos((double) a));
|
||||
v->z = (pl_Float) (r*sin((double) a));
|
||||
v->xformedx = (0.5 + (cos((double) a)*0.5));
|
||||
v->xformedy = (0.5 + (sin((double) a)*0.5));
|
||||
a += da;
|
||||
v++;
|
||||
}
|
||||
if (cap && div != 3) {
|
||||
v->y = h / -2.0f;
|
||||
v->x = v->z = 0.0f;
|
||||
v->xformedx = 0.5;
|
||||
v->xformedy = 0.5;
|
||||
v++;
|
||||
}
|
||||
f = o->Faces.Get();
|
||||
for (i = 1; i <= div; i ++) {
|
||||
f->VertexIndices[0] = 0;
|
||||
f->VertexIndices[1] = o->Vertices.Get() + (i == div ? 1 : i + 1) - o->Vertices.Get();
|
||||
f->VertexIndices[2] = o->Vertices.Get() + i - o->Vertices.Get();
|
||||
f->MappingU[0][0] = o->Vertices.Get()[0].xformedx;
|
||||
f->MappingV[0][0] = o->Vertices.Get()[0].xformedy;
|
||||
f->MappingU[0][1] = o->Vertices.Get()[(i==div?1:i+1)].xformedx;
|
||||
f->MappingV[0][1] = o->Vertices.Get()[(i==div?1:i+1)].xformedy;
|
||||
f->MappingU[0][2] = o->Vertices.Get()[i].xformedx;
|
||||
f->MappingV[0][2] = o->Vertices.Get()[i].xformedy;
|
||||
f->Material = m;
|
||||
f++;
|
||||
}
|
||||
if (cap) {
|
||||
if (div == 3) {
|
||||
f->VertexIndices[0] = 1;
|
||||
f->VertexIndices[1] = 2;
|
||||
f->VertexIndices[2] = 3;
|
||||
f->MappingU[0][0] = o->Vertices.Get()[1].xformedx;
|
||||
f->MappingV[0][0] = o->Vertices.Get()[1].xformedy;
|
||||
f->MappingU[0][1] = o->Vertices.Get()[2].xformedx;
|
||||
f->MappingV[0][1] = o->Vertices.Get()[2].xformedy;
|
||||
f->MappingU[0][2] = o->Vertices.Get()[3].xformedx;
|
||||
f->MappingV[0][2] = o->Vertices.Get()[3].xformedy;
|
||||
f->Material = m;
|
||||
f++;
|
||||
} else {
|
||||
for (i = 1; i <= div; i ++) {
|
||||
f->VertexIndices[0] = div + 1;
|
||||
f->VertexIndices[1] = i;
|
||||
f->VertexIndices[2] = (i==div ? 1 : i+1);
|
||||
f->MappingU[0][0] = o->Vertices.Get()[div+1].xformedx;
|
||||
f->MappingV[0][0] = o->Vertices.Get()[div+1].xformedy;
|
||||
f->MappingU[0][1] = o->Vertices.Get()[i].xformedx;
|
||||
f->MappingV[0][1] = o->Vertices.Get()[i].xformedy;
|
||||
f->MappingU[0][2] = o->Vertices.Get()[i==div?1:i+1].xformedx;
|
||||
f->MappingV[0][2] = o->Vertices.Get()[i==div?1:i+1].xformedy;
|
||||
f->Material = m;
|
||||
f++;
|
||||
}
|
||||
}
|
||||
}
|
||||
o->CalculateNormals();
|
||||
return (o);
|
||||
}
|
||||
|
||||
static pl_uChar verts[6*6] = {
|
||||
0,4,1, 1,4,5, 0,1,2, 3,2,1, 2,3,6, 3,7,6,
|
||||
6,7,4, 4,7,5, 1,7,3, 7,1,5, 2,6,0, 4,0,6
|
||||
};
|
||||
static pl_uChar map[24*2*3] = {
|
||||
1,0, 1,1, 0,0, 0,0, 1,1, 0,1,
|
||||
0,0, 1,0, 0,1, 1,1, 0,1, 1,0,
|
||||
0,0, 1,0, 0,1, 1,0, 1,1, 0,1,
|
||||
0,0, 1,0, 0,1, 0,1, 1,0, 1,1,
|
||||
1,0, 0,1, 0,0, 0,1, 1,0, 1,1,
|
||||
1,0, 1,1, 0,0, 0,1, 0,0, 1,1
|
||||
};
|
||||
|
||||
|
||||
pl_Obj *plMakeBox(pl_Float w, pl_Float d, pl_Float h, pl_Mat *m) {
|
||||
pl_uChar *mm = map;
|
||||
pl_uChar *vv = verts;
|
||||
pl_Obj *o;
|
||||
pl_Vertex *v;
|
||||
pl_Face *f;
|
||||
pl_uInt x;
|
||||
o = new pl_Obj(8,12);
|
||||
if (!o) return 0;
|
||||
v = o->Vertices.Get();
|
||||
v->x = -w/2; v->y = h/2; v->z = d/2; v++;
|
||||
v->x = w/2; v->y = h/2; v->z = d/2; v++;
|
||||
v->x = -w/2; v->y = h/2; v->z = -d/2; v++;
|
||||
v->x = w/2; v->y = h/2; v->z = -d/2; v++;
|
||||
v->x = -w/2; v->y = -h/2; v->z = d/2; v++;
|
||||
v->x = w/2; v->y = -h/2; v->z = d/2; v++;
|
||||
v->x = -w/2; v->y = -h/2; v->z = -d/2; v++;
|
||||
v->x = w/2; v->y = -h/2; v->z = -d/2; v++;
|
||||
f = o->Faces.Get();
|
||||
for (x = 0; x < 12; x ++) {
|
||||
f->VertexIndices[0] = *vv++;
|
||||
f->VertexIndices[1] = *vv++;
|
||||
f->VertexIndices[2] = *vv++;
|
||||
f->MappingU[0][0] = (pl_Float) *mm++;
|
||||
f->MappingV[0][0] = (pl_Float) *mm++;
|
||||
f->MappingU[0][1] = (pl_Float) *mm++;
|
||||
f->MappingV[0][1] = (pl_Float) *mm++;
|
||||
f->MappingU[0][2] = (pl_Float) *mm++;
|
||||
f->MappingV[0][2] = (pl_Float) *mm++;
|
||||
f->Material = m;
|
||||
f++;
|
||||
}
|
||||
|
||||
o->CalculateNormals();
|
||||
return (o);
|
||||
}
|
||||
|
||||
pl_Obj *plMakePlane(pl_Float w, pl_Float d, pl_uInt res, pl_Mat *m) {
|
||||
pl_Obj *o;
|
||||
pl_Vertex *v;
|
||||
pl_Face *f;
|
||||
pl_uInt x, y;
|
||||
o = new pl_Obj((res+1)*(res+1),res*res*2);
|
||||
if (!o) return 0;
|
||||
v = o->Vertices.Get();
|
||||
for (y = 0; y <= res; y ++) {
|
||||
for (x = 0; x <= res; x ++) {
|
||||
v->y = 0;
|
||||
v->x = ((x*w)/res) - w/2;
|
||||
v->z = ((y*d)/res) - d/2;
|
||||
v++;
|
||||
}
|
||||
}
|
||||
f = o->Faces.Get();
|
||||
for (y = 0; y < res; y ++) {
|
||||
for (x = 0; x < res; x ++) {
|
||||
f->VertexIndices[0] = x+(y*(res+1));
|
||||
f->MappingU[0][0] = (x)/(double)res;
|
||||
f->MappingV[0][0] = (y)/(double)res;
|
||||
f->VertexIndices[2] = x+1+(y*(res+1));
|
||||
f->MappingU[0][2] = ((x+1))/(double)res;
|
||||
f->MappingV[0][2] = (y)/(double)res;
|
||||
f->VertexIndices[1] = x+((y+1)*(res+1));
|
||||
f->MappingU[0][1] = (x)/(double)res;
|
||||
f->MappingV[0][1] = ((y+1))/(double)res;
|
||||
f->Material = m;
|
||||
f++;
|
||||
f->VertexIndices[0] = x+((y+1)*(res+1));
|
||||
f->MappingU[0][0] = (x)/(double)res;
|
||||
f->MappingV[0][0] = ((y+1))/(double)res;
|
||||
f->VertexIndices[2] = x+1+(y*(res+1));
|
||||
f->MappingU[0][2] = ((x+1))/(double)res;
|
||||
f->MappingV[0][2] = (y)/(double)res;
|
||||
f->VertexIndices[1] = x+1+((y+1)*(res+1));
|
||||
f->MappingU[0][1] = ((x+1))/(double)res;
|
||||
f->MappingV[0][1] = ((y+1))/(double)res;
|
||||
f->Material = m;
|
||||
f++;
|
||||
}
|
||||
}
|
||||
o->CalculateNormals();
|
||||
return (o);
|
||||
}
|
||||
67
oversampling/WDL/plush2/pl_math.cpp
Normal file
67
oversampling/WDL/plush2/pl_math.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/******************************************************************************
|
||||
Plush Version 1.2
|
||||
math.c
|
||||
Math and Matrix Control
|
||||
Copyright (c) 1996-2000, Justin Frankel
|
||||
******************************************************************************/
|
||||
|
||||
#include "plush.h"
|
||||
|
||||
void plMatrixRotate(pl_Float matrix[], pl_uChar m, pl_Float Deg) {
|
||||
pl_uChar m1, m2;
|
||||
double c,s;
|
||||
double d= Deg * PL_PI / 180.0;
|
||||
memset(matrix,0,sizeof(pl_Float)*16);
|
||||
matrix[((m-1)<<2)+m-1] = matrix[15] = 1.0;
|
||||
m1 = (m % 3);
|
||||
m2 = ((m1+1) % 3);
|
||||
c = cos(d); s = sin(d);
|
||||
matrix[(m1<<2)+m1]=(pl_Float)c; matrix[(m1<<2)+m2]=(pl_Float)s;
|
||||
matrix[(m2<<2)+m2]=(pl_Float)c; matrix[(m2<<2)+m1]=(pl_Float)-s;
|
||||
}
|
||||
|
||||
void plMatrixTranslate(pl_Float m[], pl_Float x, pl_Float y, pl_Float z) {
|
||||
memset(m,0,sizeof(pl_Float)*16);
|
||||
m[0] = m[4+1] = m[8+2] = m[12+3] = 1.0;
|
||||
m[0+3] = x; m[4+3] = y; m[8+3] = z;
|
||||
}
|
||||
|
||||
void plMatrixMultiply(pl_Float *dest, const pl_Float src[]) {
|
||||
pl_Float temp[16];
|
||||
pl_uInt i;
|
||||
memcpy(temp,dest,sizeof(pl_Float)*16);
|
||||
for (i = 0; i < 16; i += 4) {
|
||||
*dest++ = src[i+0]*temp[(0<<2)+0]+src[i+1]*temp[(1<<2)+0]+
|
||||
src[i+2]*temp[(2<<2)+0]+src[i+3]*temp[(3<<2)+0];
|
||||
*dest++ = src[i+0]*temp[(0<<2)+1]+src[i+1]*temp[(1<<2)+1]+
|
||||
src[i+2]*temp[(2<<2)+1]+src[i+3]*temp[(3<<2)+1];
|
||||
*dest++ = src[i+0]*temp[(0<<2)+2]+src[i+1]*temp[(1<<2)+2]+
|
||||
src[i+2]*temp[(2<<2)+2]+src[i+3]*temp[(3<<2)+2];
|
||||
*dest++ = src[i+0]*temp[(0<<2)+3]+src[i+1]*temp[(1<<2)+3]+
|
||||
src[i+2]*temp[(2<<2)+3]+src[i+3]*temp[(3<<2)+3];
|
||||
}
|
||||
}
|
||||
|
||||
void plMatrixApply(pl_Float *m, pl_Float x, pl_Float y, pl_Float z,
|
||||
pl_Float *outx, pl_Float *outy, pl_Float *outz) {
|
||||
*outx = x*m[0] + y*m[1] + z*m[2] + m[3];
|
||||
*outy = x*m[4] + y*m[5] + z*m[6] + m[7];
|
||||
*outz = x*m[8] + y*m[9] + z*m[10] + m[11];
|
||||
}
|
||||
|
||||
pl_Float plDotProduct(pl_Float x1, pl_Float y1, pl_Float z1,
|
||||
pl_Float x2, pl_Float y2, pl_Float z2) {
|
||||
return ((x1*x2)+(y1*y2)+(z1*z2));
|
||||
}
|
||||
|
||||
void plNormalizeVector(pl_Float *x, pl_Float *y, pl_Float *z) {
|
||||
double length;
|
||||
length = (*x)*(*x)+(*y)*(*y)+(*z)*(*z);
|
||||
if (length > 0.0000000001) {
|
||||
pl_Float t = (pl_Float)sqrt(length);
|
||||
*x /= t;
|
||||
*y /= t;
|
||||
*z /= t;
|
||||
} else *x = *y = *z = 0.0;
|
||||
}
|
||||
|
||||
129
oversampling/WDL/plush2/pl_obj.cpp
Normal file
129
oversampling/WDL/plush2/pl_obj.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
/******************************************************************************
|
||||
Plush Version 1.2
|
||||
obj.c
|
||||
Object control
|
||||
Copyright (c) 1996-2000, Justin Frankel
|
||||
******************************************************************************/
|
||||
|
||||
#include "plush.h"
|
||||
|
||||
void pl_Obj::Scale(pl_Float s) {
|
||||
int i = Vertices.GetSize();
|
||||
pl_Vertex *v = Vertices.Get();
|
||||
while (i--) {
|
||||
v->x *= s; v->y *= s; v->z *= s; v++;
|
||||
}
|
||||
for (i = 0; i < Children.GetSize(); i ++)
|
||||
if (Children.Get(i)) Children.Get(i)->Scale(s);
|
||||
}
|
||||
|
||||
void pl_Obj::Stretch(pl_Float x, pl_Float y, pl_Float z) {
|
||||
int i = Vertices.GetSize();
|
||||
pl_Vertex *v = Vertices.Get();
|
||||
while (i--) {
|
||||
v->x *= x; v->y *= y; v->z *= z; v++;
|
||||
}
|
||||
for (i = 0; i < Children.GetSize(); i ++)
|
||||
if (Children.Get(i)) Children.Get(i)->Stretch(x,y,z);
|
||||
}
|
||||
|
||||
void pl_Obj::Translate(pl_Float x, pl_Float y, pl_Float z) {
|
||||
int i = Vertices.GetSize();
|
||||
pl_Vertex *v = Vertices.Get();
|
||||
while (i--) {
|
||||
v->x += x; v->y += y; v->z += z; v++;
|
||||
}
|
||||
for (i = 0; i < Children.GetSize(); i ++)
|
||||
if (Children.Get(i)) Children.Get(i)->Translate(x,y,z);
|
||||
}
|
||||
|
||||
void pl_Obj::FlipNormals() {
|
||||
int i = Vertices.GetSize();
|
||||
pl_Vertex *v = Vertices.Get();
|
||||
pl_Face *f = Faces.Get();
|
||||
while (i--) {
|
||||
v->nx = - v->nx; v->ny = - v->ny; v->nz = - v->nz; v++;
|
||||
}
|
||||
i = Faces.GetSize();
|
||||
while (i--) {
|
||||
f->nx = - f->nx; f->ny = - f->ny; f->nz = - f->nz;
|
||||
f++;
|
||||
}
|
||||
for (i = 0; i < Children.GetSize(); i ++)
|
||||
if (Children.Get(i)) Children.Get(i)->FlipNormals();
|
||||
}
|
||||
|
||||
|
||||
pl_Obj *pl_Obj::Clone() {
|
||||
int i;
|
||||
pl_Obj *out;
|
||||
if (!(out = new pl_Obj(Vertices.GetSize(),Faces.GetSize()))) return 0;
|
||||
for (i = 0; i < Children.GetSize(); i ++)
|
||||
out->Children.Add(Children.Get(i) ? Children.Get(i)->Clone() : NULL);
|
||||
|
||||
out->Xa = Xa; out->Ya = Ya; out->Za = Za;
|
||||
out->Xp = Xp; out->Yp = Yp; out->Zp = Zp;
|
||||
out->GenMatrix = GenMatrix;
|
||||
memcpy(out->Matrix,Matrix,sizeof(Matrix));
|
||||
memcpy(out->Vertices.Get(), Vertices.Get(), sizeof(pl_Vertex) * Vertices.GetSize());
|
||||
memcpy(out->Faces.Get(),Faces.Get(),sizeof(pl_Face) * Faces.GetSize());
|
||||
return out;
|
||||
}
|
||||
|
||||
void pl_Obj::SetMaterial(pl_Mat *m, pl_Bool th) {
|
||||
pl_sInt32 i = Faces.GetSize();
|
||||
pl_Face *f = Faces.Get();
|
||||
while (i--) (f++)->Material = m;
|
||||
if (th) for (i = 0; i < Children.GetSize(); i++)
|
||||
if (Children.Get(i)) Children.Get(i)->SetMaterial(m,true);
|
||||
}
|
||||
|
||||
void pl_Obj::CalculateNormals() {
|
||||
int i;
|
||||
pl_Vertex *v = Vertices.Get();
|
||||
pl_Face *f = Faces.Get();
|
||||
double x1, x2, y1, y2, z1, z2;
|
||||
i = Vertices.GetSize();
|
||||
while (i--) {
|
||||
v->nx = 0.0; v->ny = 0.0; v->nz = 0.0;
|
||||
v++;
|
||||
}
|
||||
i = Faces.GetSize();
|
||||
while (i--) {
|
||||
pl_Vertex *vp=Vertices.Get();
|
||||
pl_Vertex *fVertices[3] = {
|
||||
vp+f->VertexIndices[0],
|
||||
vp+f->VertexIndices[1],
|
||||
vp+f->VertexIndices[2],
|
||||
};
|
||||
x1 = fVertices[0]->x-fVertices[1]->x;
|
||||
x2 = fVertices[0]->x-fVertices[2]->x;
|
||||
y1 = fVertices[0]->y-fVertices[1]->y;
|
||||
y2 = fVertices[0]->y-fVertices[2]->y;
|
||||
z1 = fVertices[0]->z-fVertices[1]->z;
|
||||
z2 = fVertices[0]->z-fVertices[2]->z;
|
||||
f->nx = (pl_Float) (y1*z2 - z1*y2);
|
||||
f->ny = (pl_Float) (z1*x2 - x1*z2);
|
||||
f->nz = (pl_Float) (x1*y2 - y1*x2);
|
||||
plNormalizeVector(&f->nx, &f->ny, &f->nz);
|
||||
fVertices[0]->nx += f->nx;
|
||||
fVertices[0]->ny += f->ny;
|
||||
fVertices[0]->nz += f->nz;
|
||||
fVertices[1]->nx += f->nx;
|
||||
fVertices[1]->ny += f->ny;
|
||||
fVertices[1]->nz += f->nz;
|
||||
fVertices[2]->nx += f->nx;
|
||||
fVertices[2]->ny += f->ny;
|
||||
fVertices[2]->nz += f->nz;
|
||||
f++;
|
||||
}
|
||||
v = Vertices.Get();
|
||||
i = Vertices.GetSize();
|
||||
do {
|
||||
plNormalizeVector(&v->nx, &v->ny, &v->nz);
|
||||
v++;
|
||||
} while (--i);
|
||||
|
||||
for (i = 0; i < Children.GetSize(); i ++)
|
||||
if (Children.Get(i)) Children.Get(i)->CalculateNormals();
|
||||
}
|
||||
446
oversampling/WDL/plush2/pl_pf_tex.h
Normal file
446
oversampling/WDL/plush2/pl_pf_tex.h
Normal file
@@ -0,0 +1,446 @@
|
||||
|
||||
static void
|
||||
#ifdef PL_PF_MULTITEX
|
||||
PLMTexTri
|
||||
#else
|
||||
PLTexTri
|
||||
#endif
|
||||
(LICE_pixel *gmem, int swidth, pl_Face *TriFace, pl_ZBuffer *zbuf, int zfb_width, bool zb_update,
|
||||
int solidalpha, int solidcomb, LICE_IBitmap *tex, pl_Float *texscales, int texalpha, int texcomb, int texmap
|
||||
#ifdef PL_PF_MULTITEX
|
||||
, LICE_IBitmap *tex2, int tex2alpha, int tex2comb, int texmap2
|
||||
#endif
|
||||
|
||||
)
|
||||
{
|
||||
pl_sInt32 C1[3], C3[3], C2[3], dC2[3]={0}, dCL[3]={0},dC1[3]={0}, dX2=0, dX1=0;
|
||||
pl_Float dZ2=0, dZL=0,dZ1=0;
|
||||
|
||||
PUTFACE_SORT();
|
||||
|
||||
|
||||
solidcomb&=LICE_BLIT_MODE_MASK;
|
||||
if (solidcomb == 0 && solidalpha == 256) solidcomb=-1;
|
||||
else if (solidalpha==0) solidcomb=-2; // ignore
|
||||
int solidalpha2=(256-solidalpha)*256;
|
||||
|
||||
|
||||
pl_Float dU2=0,dV2=0,dUL=0,dVL=0;
|
||||
pl_Float dU1=0, dV1=0;
|
||||
bool bilinear = (texcomb&LICE_BLIT_FILTER_MASK)==LICE_BLIT_FILTER_BILINEAR;
|
||||
texcomb&=LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA;
|
||||
if (texcomb==LICE_BLIT_MODE_COPY && texalpha==256) texcomb=-1;
|
||||
else if (texalpha==0) texcomb=-2;
|
||||
int texalpha2=(256-texalpha);
|
||||
|
||||
int tex_rowspan=0;
|
||||
LICE_pixel *texture=NULL;
|
||||
int tex_w=16,tex_h=16;
|
||||
|
||||
#if defined(PLUSH_NO_SOLIDGOURAUD) || defined(PLUSH_NO_TEXTURE)
|
||||
if (tex)
|
||||
#endif
|
||||
{
|
||||
texture=tex->getBits();
|
||||
tex_rowspan = tex->getRowSpan();
|
||||
if (tex->isFlipped())
|
||||
{
|
||||
texture += tex_rowspan*(tex->getHeight()-1);
|
||||
tex_rowspan=-tex_rowspan;
|
||||
}
|
||||
tex_w=tex->getWidth();
|
||||
tex_h=tex->getHeight();
|
||||
tex_rowspan *= 4;
|
||||
}
|
||||
pl_sInt32 MappingU_Max=tex_w<<16, MappingV_Max=tex_h<<16;
|
||||
texscales[0]*=MappingU_Max;
|
||||
texscales[1]*=MappingV_Max;
|
||||
tex_w *= 4;
|
||||
|
||||
#ifdef PL_PF_MULTITEX
|
||||
|
||||
pl_Float dU2_2=0,dV2_2=0,dUL_2=0,dVL_2=0;
|
||||
pl_Float dU1_2=0, dV1_2=0;
|
||||
int tex_w_2=16,tex_h_2=16;
|
||||
bool bilinear2 = (tex2comb&LICE_BLIT_FILTER_MASK)==LICE_BLIT_FILTER_BILINEAR;
|
||||
tex2comb&=LICE_BLIT_MODE_MASK|LICE_BLIT_USE_ALPHA;
|
||||
if (tex2comb==LICE_BLIT_MODE_COPY && tex2alpha==256) tex2comb=-1;
|
||||
else if (tex2alpha==0) tex2comb=-2;
|
||||
int tex2alpha2=(256-tex2alpha);
|
||||
LICE_pixel *texture_2=NULL;
|
||||
int tex_rowspan_2 = 0;
|
||||
pl_sInt32 MappingU_Max_2, MappingV_Max_2;
|
||||
|
||||
#ifdef PLUSH_NO_TEXTURE
|
||||
if (tex2)
|
||||
#endif
|
||||
{
|
||||
tex_w_2=tex2->getWidth();
|
||||
tex_h_2=tex2->getHeight();
|
||||
texture_2=tex2->getBits();
|
||||
tex_rowspan_2 = tex2->getRowSpan();
|
||||
if (tex2->isFlipped())
|
||||
{
|
||||
texture_2 += tex_rowspan_2*(tex2->getHeight()-1);
|
||||
tex_rowspan_2=-tex_rowspan_2;
|
||||
}
|
||||
tex_rowspan_2 *= 4;
|
||||
}
|
||||
MappingU_Max_2=tex_w_2<<16;
|
||||
MappingV_Max_2=tex_h_2<<16;
|
||||
texscales[2]*=MappingU_Max_2;
|
||||
texscales[3]*=MappingV_Max_2;
|
||||
tex_w_2 *= 4;
|
||||
#endif
|
||||
|
||||
|
||||
pl_uChar nm = TriFace->Material->PerspectiveCorrect;
|
||||
pl_uChar nmb = 0; while (nm) { nmb++; nm >>= 1; }
|
||||
nmb = plMin(6,nmb);
|
||||
nm = 1<<nmb;
|
||||
|
||||
|
||||
pl_Float Z1 = TriFace->Scrz[i0];
|
||||
pl_Float Z2 = TriFace->Scrz[i1];
|
||||
pl_Float Z3 = TriFace->Scrz[i2];
|
||||
|
||||
pl_Float MappingU1=TriFace->MappingU[texmap][i0]*texscales[0]*Z1;
|
||||
pl_Float MappingV1=TriFace->MappingV[texmap][i0]*texscales[1]*Z1;
|
||||
pl_Float MappingU2=TriFace->MappingU[texmap][i1]*texscales[0]*Z2;
|
||||
pl_Float MappingV2=TriFace->MappingV[texmap][i1]*texscales[1]*Z2;
|
||||
pl_Float MappingU3=TriFace->MappingU[texmap][i2]*texscales[0]*Z3;
|
||||
pl_Float MappingV3=TriFace->MappingV[texmap][i2]*texscales[1]*Z3;
|
||||
|
||||
#ifdef PL_PF_MULTITEX
|
||||
pl_Float MappingU1_2=TriFace->MappingU[texmap2][i0]*texscales[2]*Z1;
|
||||
pl_Float MappingV1_2=TriFace->MappingV[texmap2][i0]*texscales[3]*Z1;
|
||||
pl_Float MappingU2_2=TriFace->MappingU[texmap2][i1]*texscales[2]*Z2;
|
||||
pl_Float MappingV2_2=TriFace->MappingV[texmap2][i1]*texscales[3]*Z2;
|
||||
pl_Float MappingU3_2=TriFace->MappingU[texmap2][i2]*texscales[2]*Z3;
|
||||
pl_Float MappingV3_2=TriFace->MappingV[texmap2][i2]*texscales[3]*Z3;
|
||||
#endif
|
||||
|
||||
int a;
|
||||
for(a=0;a<3;a++)
|
||||
{
|
||||
C1[a] = (pl_sInt32) (TriFace->Shades[i0][a]*(1<<24));
|
||||
C2[a] = (pl_sInt32) (TriFace->Shades[i1][a]*(1<<24));
|
||||
C3[a] = (pl_sInt32) (TriFace->Shades[i2][a]*(1<<24));
|
||||
}
|
||||
|
||||
pl_Float U1, U2;
|
||||
U1 = U2 = MappingU1;
|
||||
pl_Float V1,V2;
|
||||
V1 = V2 = MappingV1;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
pl_Float U1_2, U2_2;
|
||||
U1_2 = U2_2 = MappingU1_2;
|
||||
pl_Float V1_2, V2_2;
|
||||
V1_2 = V2_2 = MappingV1_2;
|
||||
#endif
|
||||
|
||||
pl_sInt32 X2,X1;
|
||||
X2 = X1 = Scrx[i0];
|
||||
pl_sInt32 Y0 = Scry[i0];
|
||||
pl_sInt32 Y1 = Scry[i1];
|
||||
pl_sInt32 Y2 = Scry[i2];
|
||||
|
||||
|
||||
{
|
||||
pl_sInt32 dY = Y2-Y0;
|
||||
if (dY) {
|
||||
dX2 = (Scrx[i2] - X1) / dY;
|
||||
|
||||
pl_Float v = 1.0/dY;
|
||||
for(a=0;a<3;a++) dC2[a] = (pl_sInt32) ((C3[a] - C1[a]) * v);
|
||||
dZ2 = (Z3 - Z1) * v;
|
||||
dU2 = (MappingU3 - U1) * v;
|
||||
dV2 = (MappingV3 - V1) * v;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
dU2_2 = (MappingU3_2 - U1_2) * v;
|
||||
dV2_2 = (MappingV3_2 - V1_2) * v;
|
||||
#endif
|
||||
}
|
||||
dY = Y1-Y0;
|
||||
if (dY) {
|
||||
dX1 = (Scrx[i1] - X1) / dY;
|
||||
pl_Float v=1.0/dY;
|
||||
dZ1 = (Z2 - Z1) * v;
|
||||
for(a=0;a<3;a++) dC1[a] = (pl_sInt32) ((C2[a] - C1[a]) * v);
|
||||
dU1 = (MappingU2 - U1) * v;
|
||||
dV1 = (MappingV2 - V1) * v;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
dU1_2 = (MappingU2_2 - U1_2) * v;
|
||||
dV1_2 = (MappingV2_2 - V1_2) * v;
|
||||
#endif
|
||||
if (dX2 < dX1) {
|
||||
SWAP(dX1,dX2,pl_sInt32);
|
||||
SWAP(dU1,dU2,pl_Float);
|
||||
SWAP(dV1,dV2,pl_Float);
|
||||
#ifdef PL_PF_MULTITEX
|
||||
SWAP(dU1_2,dU2_2,pl_Float);
|
||||
SWAP(dV1_2,dV2_2,pl_Float);
|
||||
#endif
|
||||
SWAP(dZ1,dZ2,pl_Float);
|
||||
for(a=0;a<3;a++)
|
||||
SWAP(dC1[a],dC2[a],pl_sInt32);
|
||||
stat = 2;
|
||||
} else stat = 1;
|
||||
Z2 = Z1;
|
||||
C2[0] = C1[0];
|
||||
C2[1] = C1[1];
|
||||
C2[2] = C1[2];
|
||||
|
||||
} else {
|
||||
if (Scrx[i1] > X1) {
|
||||
X2 = Scrx[i1];
|
||||
U2 = MappingU2;
|
||||
V2 = MappingV2;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
U2_2 = MappingU2_2;
|
||||
V2_2 = MappingV2_2;
|
||||
#endif
|
||||
stat = 2|4;
|
||||
} else {
|
||||
X1 = Scrx[i1];
|
||||
SWAP(Z1,Z2,pl_Float)
|
||||
for(a=0;a<3;a++) SWAP(C1[a],C2[a],pl_sInt32);
|
||||
U1 = MappingU2;
|
||||
V1 = MappingV2;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
U1_2 = MappingU2_2;
|
||||
V1_2 = MappingV2_2;
|
||||
#endif
|
||||
stat = 1|8;
|
||||
}
|
||||
}
|
||||
pl_sInt32 tmp = (dX1-dX2)*dY;
|
||||
if (tmp) {
|
||||
pl_Float v=(1<<XPOS_BITS)/(double)tmp;
|
||||
dUL = ((dU1-dU2)*dY)*v;
|
||||
dVL = ((dV1-dV2)*dY)*v;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
dUL_2 = ((dU1_2-dU2_2)*dY)*v;
|
||||
dVL_2 = ((dV1_2-dV2_2)*dY)*v;
|
||||
#endif
|
||||
dZL = ((dZ1-dZ2)*dY)*v;
|
||||
for(a=0;a<3;a++) dCL[a] = (pl_sInt32) ( ((dC1[a]-dC2[a])*dY)*v);
|
||||
} else {
|
||||
tmp = X2-X1;
|
||||
if (tmp) {
|
||||
pl_Float v=(1<<XPOS_BITS)/(double)tmp;
|
||||
dUL = (U2-U1)*v;
|
||||
dVL = (V2-V1)*v;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
dUL_2 = (U2_2-U1_2)*v;
|
||||
dVL_2 = (V2_2-V1_2)*v;
|
||||
#endif
|
||||
dZL = (Z2-Z1)*v;
|
||||
for(a=0;a<3;a++) dCL[a] = (pl_sInt32) ((C2[a]-C1[a])*v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gmem += (Y0 * swidth);
|
||||
zbuf += (Y0 * zfb_width);
|
||||
|
||||
|
||||
pl_Float pdZL = dZL * nm;
|
||||
dUL *= nm;
|
||||
dVL *= nm;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
dUL_2 *= nm;
|
||||
dVL_2 *= nm;
|
||||
#endif
|
||||
Y1 -= Y0;
|
||||
Y0 = Y2-Y0;
|
||||
while (Y0--) {
|
||||
if (!Y1--) {
|
||||
pl_sInt32 dY = Y2-Scry[i1];
|
||||
if (dY) {
|
||||
DO_STAT_XDELTAS
|
||||
|
||||
pl_Float tmp=1.0/dY;
|
||||
dZ1 = (Z3-Z1)*tmp;
|
||||
for(a=0;a<3;a++) dC1[a] = (pl_sInt32)((C3[a]-C1[a])*tmp);
|
||||
dV1 = (MappingV3 - V1)*tmp;
|
||||
dU1 = (MappingU3 - U1)*tmp;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
dV1_2 = (MappingV3_2 - V1_2)*tmp;
|
||||
dU1_2 = (MappingU3_2 - U1_2)*tmp;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
pl_sInt32 XL1 = (X1+(1<<(XPOS_BITS-1)))>>XPOS_BITS;
|
||||
pl_sInt32 Xlen = ((X2+(1<<(XPOS_BITS-1)))>>XPOS_BITS) - XL1;
|
||||
if (Xlen > 0) {
|
||||
pl_sInt32 iUL, iVL, idUL, idVL, iULnext, iVLnext;
|
||||
pl_Float UL = U1;
|
||||
pl_Float VL = V1;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
pl_sInt32 iUL_2, iVL_2, idUL_2, idVL_2, iULnext_2, iVLnext_2;
|
||||
pl_Float UL_2 = U1_2;
|
||||
pl_Float VL_2 = V1_2;
|
||||
#endif
|
||||
pl_sInt32 CL[3] = {C1[0],C1[1], C1[2]};
|
||||
pl_Float pZL,ZL;
|
||||
pl_Float t = 1.0f / (pZL = ZL = Z1);
|
||||
gmem += XL1;
|
||||
zbuf += XL1;
|
||||
|
||||
XL1 += Xlen; // update to new line end pos so we can adjust gmem/zbuf later
|
||||
iULnext = ((pl_sInt32) (UL*t));
|
||||
iVLnext = ((pl_sInt32) (VL*t));
|
||||
#ifdef PL_PF_MULTITEX
|
||||
iULnext_2 = ((pl_sInt32) (UL_2*t));
|
||||
iVLnext_2 = ((pl_sInt32) (VL_2*t));
|
||||
#endif
|
||||
do {
|
||||
UL += dUL;
|
||||
VL += dVL;
|
||||
iUL = iULnext;
|
||||
iVL = iVLnext;
|
||||
pZL += pdZL;
|
||||
t = 1.0f/pZL;
|
||||
iULnext = ((pl_sInt32) (UL*t));
|
||||
iVLnext = ((pl_sInt32) (VL*t));
|
||||
idUL = (iULnext - iUL)>>nmb;
|
||||
idVL = (iVLnext - iVL)>>nmb;
|
||||
if (idUL>MappingU_Max) idUL=MappingU_Max;
|
||||
else if (idUL<-MappingU_Max) idUL=-MappingU_Max;
|
||||
if (idVL>MappingV_Max) idVL=MappingV_Max;
|
||||
else if (idVL<-MappingV_Max) idVL=-MappingV_Max;
|
||||
|
||||
// todo: this is slow as shit, should we force textures to be powers of two? hehe
|
||||
if (iUL<0) do iUL+=MappingU_Max; while (iUL<0);
|
||||
else while (iUL >= MappingU_Max) iUL-=MappingU_Max;
|
||||
if (iVL<0) do iVL+=MappingV_Max; while (iVL<0);
|
||||
else while (iVL >= MappingV_Max) iVL-=MappingV_Max;
|
||||
|
||||
#ifdef PL_PF_MULTITEX
|
||||
UL_2 += dUL_2;
|
||||
VL_2 += dVL_2;
|
||||
iUL_2 = iULnext_2;
|
||||
iVL_2 = iVLnext_2;
|
||||
iULnext_2 = ((pl_sInt32) (UL_2*t));
|
||||
iVLnext_2 = ((pl_sInt32) (VL_2*t));
|
||||
idUL_2 = (iULnext_2 - iUL_2)>>nmb;
|
||||
idVL_2 = (iVLnext_2 - iVL_2)>>nmb;
|
||||
if (idUL_2>MappingU_Max_2) idUL_2=MappingU_Max_2;
|
||||
else if (idUL_2<-MappingU_Max_2) idUL_2=-MappingU_Max_2;
|
||||
if (idVL_2>MappingV_Max_2) idVL_2=MappingV_Max_2;
|
||||
else if (idVL_2<-MappingV_Max_2) idVL_2=-MappingV_Max_2;
|
||||
|
||||
// todo: this is slow as shit, should we force textures to be powers of two? hehe
|
||||
if (iUL_2<0) do iUL_2+=MappingU_Max_2; while (iUL_2<0);
|
||||
else while (iUL_2 >= MappingU_Max_2) iUL_2-=MappingU_Max_2;
|
||||
if (iVL_2<0) do iVL_2+=MappingV_Max_2; while (iVL_2<0);
|
||||
else while (iVL_2 >= MappingV_Max_2) iVL_2-=MappingV_Max_2;
|
||||
|
||||
#endif
|
||||
|
||||
pl_uInt n = nm;
|
||||
Xlen -= n;
|
||||
if (Xlen < 0) n += Xlen;
|
||||
if (zfb_width) do {
|
||||
if (*zbuf < ZL) {
|
||||
if (zb_update) *zbuf = (pl_ZBuffer) ZL;
|
||||
|
||||
#ifdef PL_PF_MULTITEX
|
||||
TextureMakePixel2((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear,
|
||||
iUL,iVL,tex_w,tex_h,texture,tex_rowspan,texcomb,texalpha,texalpha2,
|
||||
bilinear2, iUL_2,iVL_2,
|
||||
tex_w_2,tex_h_2,
|
||||
texture_2,tex_rowspan_2,tex2comb,tex2alpha,tex2alpha2);
|
||||
#else
|
||||
TextureMakePixel((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear, iUL,iVL,
|
||||
tex_w,tex_h,
|
||||
texture,tex_rowspan,texcomb,texalpha,texalpha2);
|
||||
#endif
|
||||
|
||||
}
|
||||
zbuf++;
|
||||
gmem++;
|
||||
ZL += dZL;
|
||||
CL[0] += dCL[0];
|
||||
CL[1] += dCL[1];
|
||||
CL[2] += dCL[2];
|
||||
iUL += idUL;
|
||||
iVL += idVL;
|
||||
|
||||
if (iUL<0) iUL+=MappingU_Max;
|
||||
else if (iUL >= MappingU_Max) iUL -= MappingU_Max;
|
||||
if (iVL<0) iVL+=MappingV_Max;
|
||||
else if (iVL >= MappingV_Max) iVL -= MappingV_Max;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
iUL_2 += idUL_2;
|
||||
iVL_2 += idVL_2;
|
||||
|
||||
if (iUL_2<0) iUL_2+=MappingU_Max_2;
|
||||
else if (iUL_2 >= MappingU_Max_2) iUL_2 -= MappingU_Max_2;
|
||||
if (iVL_2<0) iVL_2+=MappingV_Max_2;
|
||||
else if (iVL_2 >= MappingV_Max_2) iVL_2 -= MappingV_Max_2;
|
||||
#endif
|
||||
} while (--n);
|
||||
else do {
|
||||
|
||||
#ifdef PL_PF_MULTITEX
|
||||
TextureMakePixel2((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear,
|
||||
iUL,iVL,tex_w,tex_h,texture,tex_rowspan,texcomb,texalpha,texalpha2,
|
||||
bilinear2, iUL_2,iVL_2,
|
||||
tex_w_2,tex_h_2,
|
||||
texture_2,tex_rowspan_2,tex2comb,tex2alpha,tex2alpha2);
|
||||
#else
|
||||
TextureMakePixel((LICE_pixel_chan *)gmem,solidcomb,solidalpha,solidalpha2,CL, bilinear, iUL,iVL,
|
||||
tex_w,tex_h,
|
||||
texture,tex_rowspan,texcomb,texalpha,texalpha2);
|
||||
#endif
|
||||
|
||||
|
||||
gmem++;
|
||||
CL[0] += dCL[0];
|
||||
CL[1] += dCL[1];
|
||||
CL[2] += dCL[2];
|
||||
iUL += idUL;
|
||||
iVL += idVL;
|
||||
|
||||
if (iUL<0) iUL+=MappingU_Max;
|
||||
else if (iUL >= MappingU_Max) iUL -= MappingU_Max;
|
||||
if (iVL<0) iVL+=MappingV_Max;
|
||||
else if (iVL >= MappingV_Max) iVL -= MappingV_Max;
|
||||
|
||||
#ifdef PL_PF_MULTITEX
|
||||
iUL_2 += idUL_2;
|
||||
iVL_2 += idVL_2;
|
||||
|
||||
if (iUL_2<0) iUL_2+=MappingU_Max_2;
|
||||
else if (iUL_2 >= MappingU_Max_2) iUL_2 -= MappingU_Max_2;
|
||||
if (iVL_2<0) iVL_2+=MappingV_Max_2;
|
||||
else if (iVL_2 >= MappingV_Max_2) iVL_2 -= MappingV_Max_2;
|
||||
#endif
|
||||
|
||||
} while (--n);
|
||||
} while (Xlen > 0);
|
||||
gmem += swidth-XL1;
|
||||
zbuf += zfb_width-XL1;
|
||||
} else { // xlen <=0 ,no drawing
|
||||
gmem += swidth;
|
||||
zbuf += zfb_width;
|
||||
}
|
||||
Z1 += dZ1;
|
||||
U1 += dU1;
|
||||
V1 += dV1;
|
||||
#ifdef PL_PF_MULTITEX
|
||||
U1_2 += dU1_2;
|
||||
V1_2 += dV1_2;
|
||||
#endif
|
||||
X1 += dX1;
|
||||
X2 += dX2;
|
||||
C1[0] += dC1[0];
|
||||
C1[1] += dC1[1];
|
||||
C1[2] += dC1[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
713
oversampling/WDL/plush2/pl_putface.cpp
Normal file
713
oversampling/WDL/plush2/pl_putface.cpp
Normal file
@@ -0,0 +1,713 @@
|
||||
#include "plush.h"
|
||||
#include "../lice/lice_combine.h"
|
||||
|
||||
//#define PLUSH_NO_SOLIDFLAT // make non-texturemapped flat shading optimized engine
|
||||
//#define PLUSH_NO_SOLIDGOURAUD // disable non-texturemapped gouraud optimized engine
|
||||
//#define PLUSH_NO_TEXTURE // disable single-texture optimized engine
|
||||
//#define PLUSH_NO_MULTITEXTURE // disable multitexture (this can do any of em)
|
||||
#define XPOS_BITS 19 // allows 2^13 max screen width, or 8192px
|
||||
|
||||
#define SWAP(a,b,t) { t ____tmp=(a); (a)=(b); (b)=____tmp; }
|
||||
|
||||
#define PUTFACE_SORT() \
|
||||
int i0 = 0; int i1 = 1; int i2 = 2; int stat; \
|
||||
if (TriFace->Scry[0] > TriFace->Scry[1]) { i0 = 1; i1 = 0; } \
|
||||
if (TriFace->Scry[i0] > TriFace->Scry[2]) { SWAP(i0,i2,int); } \
|
||||
if (TriFace->Scry[i1] > TriFace->Scry[i2]) { SWAP(i1,i2,int); } \
|
||||
int Scrx[3] = {(int)(TriFace->Scrx[0]*(1<<XPOS_BITS)), (int)(TriFace->Scrx[1]*(1<<XPOS_BITS)),(int)(TriFace->Scrx[2]*(1<<XPOS_BITS))}; \
|
||||
int Scry[3] = {(int) (TriFace->Scry[0]+0.5), (int) (TriFace->Scry[1]+0.5), (int) (TriFace->Scry[2]+0.5)}; \
|
||||
|
||||
#define DO_STAT_XDELTAS \
|
||||
if (stat & 1) { \
|
||||
dX1 = (Scrx[i2]-(X1 = Scrx[i1]))/dY; \
|
||||
if (stat & 8) dX2 = (Scrx[i2]-(X2 = Scrx[i0]))/dY; \
|
||||
} \
|
||||
else if (stat & 2) { \
|
||||
dX2 = (Scrx[i2]-(X2 = Scrx[i1]))/dY; \
|
||||
if (stat & 4) dX1 = (Scrx[i2]-(X1 = Scrx[i0]))/dY; \
|
||||
}
|
||||
|
||||
|
||||
static inline void OverlayBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int usea)
|
||||
{
|
||||
int da=(256-usea)*128;
|
||||
int srcr = r*usea+da, srcg = g*usea+da, srcb = b*usea+da, srca = usea*a + da;
|
||||
red = ( red*( (red*(32768-srcr))/256 + srcr ) )/32768;
|
||||
green = ( green*( (green*(32768-srcg))/256 + srcg ) )/32768;
|
||||
blue = ( blue*( (blue*(32768-srcb))/256 + srcb ) )/32768;
|
||||
alpha = ( alpha*( (alpha*(32768-srca))/256 + srca ) )/32768;
|
||||
}
|
||||
|
||||
static inline void MulBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int ta)
|
||||
{
|
||||
int ta2=(256-ta)*256;
|
||||
red = (r*ta*red + red*ta2)/65536;
|
||||
green = (g*ta*green + green*ta2)/65536;
|
||||
blue = (b*ta*blue + blue*ta2)/65536;
|
||||
alpha = (a*ta*alpha + alpha*ta2)/65536;
|
||||
}
|
||||
|
||||
|
||||
static inline void AdjustHSV(int &red, int &green, int &blue, int r, int g, int b, int texalpha)
|
||||
{
|
||||
int h,s,v;
|
||||
__LICE_RGB2HSV(red,green,blue,&h,&s,&v);
|
||||
h+=(((r+r/2) - 192) * texalpha)/256;
|
||||
if (h<0)h+=384;
|
||||
else if (h>=384) h-=384;
|
||||
s+=((g-128)*texalpha)/256;
|
||||
if (s&~0xff)
|
||||
{
|
||||
if (s<0)s=0;
|
||||
else s=255;
|
||||
}
|
||||
v+=((b-128)*texalpha)/256;
|
||||
if (v&~0xff)
|
||||
{
|
||||
if (v<0)v=0;
|
||||
else v=255;
|
||||
}
|
||||
__LICE_HSV2RGB(h,s,v,&red,&green,&blue);
|
||||
}
|
||||
|
||||
static inline void DodgeBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int ta)
|
||||
{
|
||||
int src_r = 256-r*ta/256;
|
||||
int src_g = 256-g*ta/256;
|
||||
int src_b = 256-b*ta/256;
|
||||
int src_a = 256-(a*ta)/256;
|
||||
|
||||
red = src_r > 1 ? 256*red / src_r : 256*red;
|
||||
green = src_g > 1 ? 256*green / src_g : 256*green;
|
||||
blue = src_b > 1 ? 256*blue / src_b : 256*blue;
|
||||
alpha = src_a > 1 ? 256*alpha / src_a : 256*alpha;
|
||||
}
|
||||
|
||||
|
||||
static void inline DoTextureCombine(int texcomb, int r, int g, int b, int a, int &red, int &green, int &blue, int &alpha, int texalpha, int texalpha2)
|
||||
{
|
||||
switch (texcomb)
|
||||
{
|
||||
case LICE_BLIT_MODE_COPY:
|
||||
red = (r*texalpha + red*texalpha2) >> 8;
|
||||
green = (g*texalpha + green*texalpha2) >> 8;
|
||||
blue = (b*texalpha + blue*texalpha2) >> 8;
|
||||
alpha = (a*texalpha + alpha*texalpha2) >> 8;
|
||||
break;
|
||||
case LICE_BLIT_MODE_ADD:
|
||||
red += (r*texalpha) >> 8;
|
||||
green += (g*texalpha) >> 8;
|
||||
blue += (b*texalpha) >> 8;
|
||||
alpha += (a*texalpha) >> 8;
|
||||
break;
|
||||
case LICE_BLIT_MODE_MUL:
|
||||
MulBlend(red,green,blue,alpha,r,g,b,a,texalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_DODGE:
|
||||
DodgeBlend(red,green,blue,alpha,r,g,b,a,texalpha);
|
||||
|
||||
break;
|
||||
case LICE_BLIT_MODE_OVERLAY:
|
||||
OverlayBlend(red,green,blue,alpha,r,g,b,a, texalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_HSVADJ:
|
||||
AdjustHSV(red,green,blue,r,g,b,texalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA:
|
||||
{
|
||||
int ta=(texalpha*(a+1));
|
||||
int ta2=(65536-ta);
|
||||
red = (r*ta + red*ta2) >> 16;
|
||||
green = (g*ta + green*ta2) >> 16;
|
||||
blue = (b*ta + blue*ta2) >> 16;
|
||||
alpha = (a*ta + alpha*ta2) >> 16;
|
||||
}
|
||||
break;
|
||||
case LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA:
|
||||
{
|
||||
int ta=(texalpha*(a+1));
|
||||
red += (r*ta) >> 16;
|
||||
green += (g*ta) >> 16;
|
||||
blue += (b*ta) >> 16;
|
||||
alpha += (a*ta) >> 16;
|
||||
}
|
||||
break;
|
||||
case LICE_BLIT_MODE_DODGE|LICE_BLIT_USE_ALPHA:
|
||||
{
|
||||
int ta=(texalpha*(a+1))/256;
|
||||
DodgeBlend(red,green,blue,alpha,r,g,b,a,ta);
|
||||
}
|
||||
break;
|
||||
case LICE_BLIT_MODE_MUL|LICE_BLIT_USE_ALPHA:
|
||||
MulBlend(red,green,blue,alpha,r,g,b,a,(texalpha*(a+1))/256);
|
||||
break;
|
||||
case LICE_BLIT_MODE_OVERLAY|LICE_BLIT_USE_ALPHA:
|
||||
OverlayBlend(red,green,blue,alpha,r,g,b,a, (texalpha*(a+1))/256);
|
||||
break;
|
||||
case LICE_BLIT_MODE_HSVADJ|LICE_BLIT_USE_ALPHA:
|
||||
AdjustHSV(red,green,blue,r,g,b,(texalpha*(a+1))/256);
|
||||
break;
|
||||
case -2:
|
||||
break;
|
||||
default:
|
||||
red=r; green=g; blue=b; alpha=a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void inline TextureMakePixelSolidCombine(int &red, int &green, int &blue, int &alpha,
|
||||
pl_sInt32 *CL, int solidcomb, int solidalpha,
|
||||
int solidalpha2,
|
||||
LICE_pixel_chan *gmemptr)
|
||||
{
|
||||
|
||||
switch (solidcomb)
|
||||
{
|
||||
case LICE_BLIT_MODE_COPY:
|
||||
red = ((CL[0]>>8)*solidalpha + gmemptr[LICE_PIXEL_R]*solidalpha2)>>16;
|
||||
green = ((CL[1]>>8)*solidalpha + gmemptr[LICE_PIXEL_G]*solidalpha2)>>16;
|
||||
blue = ((CL[2]>>8)*solidalpha + gmemptr[LICE_PIXEL_B]*solidalpha2)>>16;
|
||||
alpha = solidalpha;
|
||||
break;
|
||||
case LICE_BLIT_MODE_ADD:
|
||||
red = gmemptr[LICE_PIXEL_R] + (((CL[0]>>8)*solidalpha)>>16);
|
||||
green = gmemptr[LICE_PIXEL_G] + (((CL[1]>>8)*solidalpha)>>16);
|
||||
blue = gmemptr[LICE_PIXEL_B] + (((CL[2]>>8)*solidalpha)>>16);
|
||||
alpha = gmemptr[LICE_PIXEL_A] + solidalpha;
|
||||
break;
|
||||
case LICE_BLIT_MODE_DODGE:
|
||||
red=gmemptr[LICE_PIXEL_R];
|
||||
green=gmemptr[LICE_PIXEL_G];
|
||||
blue=gmemptr[LICE_PIXEL_B];
|
||||
alpha=gmemptr[LICE_PIXEL_A];
|
||||
DodgeBlend(red,green,blue,alpha,CL[0]>>16,CL[1]>>16,CL[2]>>16,solidalpha,solidalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_MUL:
|
||||
red=gmemptr[LICE_PIXEL_R];
|
||||
green=gmemptr[LICE_PIXEL_G];
|
||||
blue=gmemptr[LICE_PIXEL_B];
|
||||
alpha=gmemptr[LICE_PIXEL_A];
|
||||
MulBlend(red,green,blue,alpha,CL[0]>>16,CL[1]>>16,CL[2]>>16,solidalpha,solidalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_OVERLAY:
|
||||
red=gmemptr[LICE_PIXEL_R];
|
||||
green=gmemptr[LICE_PIXEL_G];
|
||||
blue=gmemptr[LICE_PIXEL_B];
|
||||
alpha=gmemptr[LICE_PIXEL_A];
|
||||
OverlayBlend(red,green,blue,alpha,CL[0]>>16,CL[1]>>16,CL[2]>>16,solidalpha, solidalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_HSVADJ:
|
||||
red=gmemptr[LICE_PIXEL_R];
|
||||
green=gmemptr[LICE_PIXEL_G];
|
||||
blue=gmemptr[LICE_PIXEL_B];
|
||||
alpha=gmemptr[LICE_PIXEL_A];
|
||||
AdjustHSV(red,green,blue,CL[0]>>16,CL[1]>>16,CL[2]>>16,solidalpha);
|
||||
break;
|
||||
case -2:
|
||||
red=gmemptr[LICE_PIXEL_R];
|
||||
green=gmemptr[LICE_PIXEL_G];
|
||||
blue=gmemptr[LICE_PIXEL_B];
|
||||
alpha=gmemptr[LICE_PIXEL_A];
|
||||
break;
|
||||
default:
|
||||
red=CL[0]>>16;
|
||||
green=CL[1]>>16;
|
||||
blue=CL[2]>>16;
|
||||
alpha=solidalpha;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void inline TextureMakePixel2(LICE_pixel_chan *gmemptr,
|
||||
int solidcomb, int solidalpha, int solidalpha2,
|
||||
pl_sInt32 *CL,
|
||||
bool bilinear,
|
||||
pl_sInt32 iUL, pl_sInt32 iVL,
|
||||
pl_sInt32 texwidth, pl_sInt32 texheight,
|
||||
LICE_pixel *texture, int tex_rowspan,
|
||||
int texcomb,
|
||||
int texalpha,
|
||||
int texalpha2,
|
||||
bool bilinear2,
|
||||
pl_sInt32 iUL_2, pl_sInt32 iVL_2,
|
||||
pl_sInt32 texwidth_2, pl_sInt32 texheight_2,
|
||||
LICE_pixel *texture2, int tex_rowspan_2,
|
||||
int tex2comb,
|
||||
int tex2alpha,
|
||||
int tex2alpha2)
|
||||
{
|
||||
|
||||
int red,green,blue,alpha;
|
||||
|
||||
TextureMakePixelSolidCombine(red,green,blue,alpha,CL,solidcomb,solidalpha,solidalpha2,gmemptr);
|
||||
|
||||
int r,g,b,a;
|
||||
|
||||
#if defined(PLUSH_NO_TEXTURE)
|
||||
if (texture)
|
||||
#endif
|
||||
{
|
||||
const int xpos=(iUL>>14)&~3;
|
||||
const int ypos=iVL>>16;
|
||||
const LICE_pixel_chan *rd = ((LICE_pixel_chan*)texture) + xpos+ypos*tex_rowspan;
|
||||
|
||||
if (bilinear)
|
||||
{
|
||||
__LICE_BilinearFilterI_2(&r,&g,&b,&a,rd,
|
||||
ypos < texheight - 1 ? rd+tex_rowspan : ((LICE_pixel_chan *)texture)+xpos,
|
||||
xpos < texwidth - 4 ? 4 : 4-texwidth,
|
||||
iUL&65535,iVL&65535);
|
||||
}
|
||||
else
|
||||
{
|
||||
r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A];
|
||||
}
|
||||
|
||||
DoTextureCombine(texcomb, r,g,b,a, red,green,blue,alpha,texalpha,texalpha2);
|
||||
}
|
||||
|
||||
#ifdef PLUSH_NO_TEXTURE
|
||||
if (texture2)
|
||||
#endif
|
||||
{
|
||||
const int xpos=(iUL_2>>14)&~3;
|
||||
const int ypos=iVL_2>>16;
|
||||
const LICE_pixel_chan *rd = ((LICE_pixel_chan*)texture2) + xpos+ypos*tex_rowspan_2;
|
||||
|
||||
if (bilinear2)
|
||||
{
|
||||
__LICE_BilinearFilterI_2(&r,&g,&b,&a,rd,
|
||||
ypos < texheight_2 - 1 ? rd+tex_rowspan_2 : ((LICE_pixel_chan *)texture2)+xpos,
|
||||
xpos < texwidth_2 - 4 ? 4 : 4-texwidth_2,
|
||||
iUL_2&65535,iVL_2&65535);
|
||||
}
|
||||
else
|
||||
{
|
||||
r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A];
|
||||
}
|
||||
|
||||
DoTextureCombine(tex2comb, r,g,b,a, red,green,blue,alpha,tex2alpha,tex2alpha2);
|
||||
}
|
||||
|
||||
_LICE_MakePixelClamp(gmemptr, red,green,blue,alpha);
|
||||
}
|
||||
|
||||
static void inline TextureMakePixel(LICE_pixel_chan *gmemptr,
|
||||
int solidcomb, int solidalpha, int solidalpha2,
|
||||
pl_sInt32 *CL,
|
||||
bool bilinear,
|
||||
pl_sInt32 iUL, pl_sInt32 iVL,
|
||||
pl_sInt32 texwidth, pl_sInt32 texheight,
|
||||
LICE_pixel *texture, int tex_rowspan,
|
||||
int texcomb,
|
||||
int texalpha,
|
||||
int texalpha2)
|
||||
{
|
||||
|
||||
int red,green,blue,alpha;
|
||||
|
||||
if (
|
||||
#ifdef PLUSH_NO_SOLIDGOURAUD
|
||||
!texture||
|
||||
#endif
|
||||
texcomb!=-1)
|
||||
TextureMakePixelSolidCombine(red,green,blue,alpha,CL,solidcomb,solidalpha,solidalpha2,gmemptr);
|
||||
|
||||
|
||||
|
||||
#ifdef PLUSH_NO_SOLIDGOURAUD
|
||||
if (texture)
|
||||
#endif
|
||||
{
|
||||
int r,g,b,a;
|
||||
const int xpos=(iUL>>14)&~3;
|
||||
const int ypos=iVL>>16;
|
||||
const LICE_pixel_chan *rd = ((LICE_pixel_chan*)texture) + xpos+ypos*tex_rowspan;
|
||||
|
||||
if (bilinear)
|
||||
{
|
||||
|
||||
__LICE_BilinearFilterI_2(&r,&g,&b,&a,rd,
|
||||
ypos < texheight - 1 ? rd+tex_rowspan : ((LICE_pixel_chan *)texture)+xpos,
|
||||
xpos < texwidth - 4 ? 4 : 4-texwidth,
|
||||
iUL&65535,iVL&65535);
|
||||
}
|
||||
else
|
||||
{
|
||||
r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A];
|
||||
}
|
||||
|
||||
DoTextureCombine(texcomb, r,g,b,a, red,green,blue,alpha,texalpha,texalpha2);
|
||||
}
|
||||
|
||||
_LICE_MakePixelClamp(gmemptr, red,green,blue,alpha);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef PLUSH_NO_TEXTURE
|
||||
#include "pl_pf_tex.h"
|
||||
#endif
|
||||
|
||||
#ifndef PLUSH_NO_MULTITEXTURE
|
||||
#define PL_PF_MULTITEX
|
||||
#include "pl_pf_tex.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
template<class Comb> class PLSolidPutFace
|
||||
{
|
||||
public:
|
||||
#ifndef PLUSH_NO_SOLIDGOURAUD
|
||||
static void SolidGouraud(LICE_pixel *gmem, int swidth, pl_Face *TriFace, int alpha, pl_ZBuffer *zbuf, int zfb_width, bool zb_update)
|
||||
{
|
||||
pl_Float dZL=0, dZ1=0, dZ2=0;
|
||||
pl_sInt32 dX1=0, dX2=0, C1[3], C2[3], dC1[3]={0}, dC2[3]={0}, dCL[3]={0}, C3[3];
|
||||
|
||||
PUTFACE_SORT();
|
||||
|
||||
|
||||
int a;
|
||||
for(a=0;a<3;a++)
|
||||
{
|
||||
C1[a] = (pl_sInt32) (TriFace->Shades[i0][a]*(1<<24));
|
||||
C2[a] = (pl_sInt32) (TriFace->Shades[i1][a]*(1<<24));
|
||||
C3[a] = (pl_sInt32) (TriFace->Shades[i2][a]*(1<<24));
|
||||
}
|
||||
pl_sInt32 X2,X1;
|
||||
X2 = X1 = Scrx[i0];
|
||||
pl_Float Z1 = TriFace->Scrz[i0];
|
||||
pl_Float Z2 = TriFace->Scrz[i1];
|
||||
pl_Float Z3 = TriFace->Scrz[i2];
|
||||
|
||||
pl_sInt32 Y0 = Scry[i0];
|
||||
pl_sInt32 Y1 = Scry[i1];
|
||||
pl_sInt32 Y2 = Scry[i2];
|
||||
|
||||
{
|
||||
pl_sInt32 dY = Y2 - Y0;
|
||||
if (dY) {
|
||||
dX2 = (Scrx[i2] - X1) / dY;
|
||||
for(a=0;a<3;a++) dC2[a] = (C3[a] - C1[a]) / dY;
|
||||
dZ2 = (Z3 - Z1) / dY;
|
||||
}
|
||||
dY = Y1 - Y0;
|
||||
if (dY) {
|
||||
dX1 = (Scrx[i1] - X1) / dY;
|
||||
for(a=0;a<3;a++)
|
||||
dC1[a] = (C2[a] - C1[a]) / dY;
|
||||
dZ1 = (Z2 - Z1) / dY;
|
||||
if (dX2 < dX1) {
|
||||
SWAP(dX2,dX1,pl_sInt32);
|
||||
for(a=0;a<3;a++) SWAP(dC1[a],dC2[a],pl_sInt32);
|
||||
SWAP(dZ1,dZ2,pl_Float);
|
||||
stat = 2;
|
||||
} else stat = 1;
|
||||
Z2 = Z1;
|
||||
C2[0] = C1[0];
|
||||
C2[1] = C1[1];
|
||||
C2[2] = C1[2];
|
||||
} else {
|
||||
if (Scrx[i1] > X1) {
|
||||
X2 = Scrx[i1];
|
||||
stat = 2|4;
|
||||
} else {
|
||||
for(a=0;a<3;a++) SWAP(C1[a],C2[a],pl_sInt32);
|
||||
SWAP(Z1,Z2,pl_Float);
|
||||
X1 = Scrx[i1];
|
||||
stat = 1|8;
|
||||
}
|
||||
}
|
||||
|
||||
pl_sInt32 tmp = (dX1-dX2)*dY;
|
||||
if (tmp) {
|
||||
double v=(1<<XPOS_BITS)/(double)tmp;
|
||||
for(a=0;a<3;a++)
|
||||
dCL[a] = (pl_sInt32) (((dC1[a]-dC2[a])*dY)*v);
|
||||
dZL = ((dZ1-dZ2)*dY)*v;
|
||||
} else {
|
||||
tmp = X2-X1;
|
||||
if (tmp) {
|
||||
double v=(1<<XPOS_BITS)/(double)tmp;
|
||||
for(a=0;a<3;a++)
|
||||
dCL[a] = (pl_sInt32) ((C2[a]-C1[a])*v);
|
||||
dZL = (Z2-Z1)*v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gmem += (Y0 * swidth);
|
||||
zbuf += (Y0 * zfb_width);
|
||||
|
||||
while (Y0 < Y2) {
|
||||
if (Y0 == Y1) {
|
||||
pl_sInt32 dY = Y2 - Scry[i1];
|
||||
if (dY) {
|
||||
double v=1.0/dY;
|
||||
dZ1 = (Z3-Z1)*v;
|
||||
dC1[0] = (pl_sInt32) ((C3[0]-C1[0])*v);
|
||||
dC1[1] = (pl_sInt32) ((C3[1]-C1[1])*v);
|
||||
dC1[2] = (pl_sInt32) ((C3[2]-C1[2])*v);
|
||||
|
||||
DO_STAT_XDELTAS
|
||||
|
||||
}
|
||||
}
|
||||
pl_sInt32 XL1 = (X1+(1<<(XPOS_BITS-1)))>>XPOS_BITS;
|
||||
pl_sInt32 XL2 = ((X2+(1<<(XPOS_BITS-1)))>>XPOS_BITS) - XL1;
|
||||
if (XL2 > 0) {
|
||||
gmem += XL1;
|
||||
XL1 += XL2;
|
||||
pl_sInt32 CL[3] = {C1[0],C1[1],C1[2]};
|
||||
if (zbuf)
|
||||
{
|
||||
pl_Float ZL = Z1;
|
||||
zbuf += XL1-XL2;
|
||||
do {
|
||||
if (*zbuf < ZL) {
|
||||
if (zb_update) *zbuf = (pl_ZBuffer) ZL;
|
||||
|
||||
Comb::doPix((LICE_pixel_chan *)gmem,CL[0]>>16,CL[1]>>16,CL[2]>>16,255,alpha);
|
||||
}
|
||||
gmem++;
|
||||
zbuf++;
|
||||
ZL += dZL;
|
||||
CL[0] += dCL[0];
|
||||
CL[1] += dCL[1];
|
||||
CL[2] += dCL[2];
|
||||
} while (--XL2);
|
||||
zbuf -= XL1;
|
||||
}
|
||||
else do {
|
||||
Comb::doPix((LICE_pixel_chan *)gmem,CL[0]>>16,CL[1]>>16,CL[2]>>16,255,alpha);
|
||||
gmem++;
|
||||
CL[0] += dCL[0];
|
||||
CL[1] += dCL[1];
|
||||
CL[2] += dCL[2];
|
||||
} while (--XL2);
|
||||
gmem -= XL1;
|
||||
}
|
||||
gmem += swidth;
|
||||
zbuf += zfb_width;
|
||||
X1 += dX1;
|
||||
X2 += dX2;
|
||||
C1[0] += dC1[0];
|
||||
C1[1] += dC1[1];
|
||||
C1[2] += dC1[2];
|
||||
Z1 += dZ1;
|
||||
Y0++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PLUSH_NO_SOLIDFLAT
|
||||
static void Solid(LICE_pixel *gmem, int swidth, pl_Face *TriFace, int alpha, pl_ZBuffer *zbuf, int zfb_width, bool zb_update)
|
||||
{
|
||||
pl_sInt32 dX1=0, dX2=0;
|
||||
pl_Float dZL=0, dZ1=0, dZ2=0;
|
||||
|
||||
PUTFACE_SORT();
|
||||
|
||||
int col0 = (int) (TriFace->Shades[0][0]*255.0);
|
||||
int col1 = (int) (TriFace->Shades[0][1]*255.0);
|
||||
int col2 = (int) (TriFace->Shades[0][2]*255.0);
|
||||
|
||||
pl_sInt32 X1,X2;
|
||||
X2 = X1 = Scrx[i0];
|
||||
pl_sInt32 Y0 = Scry[i0];
|
||||
pl_sInt32 Y1 = Scry[i1];
|
||||
pl_sInt32 Y2 = Scry[i2];
|
||||
|
||||
pl_Float Z1 = TriFace->Scrz[i0];
|
||||
pl_Float Z2 = TriFace->Scrz[i1];
|
||||
pl_Float Z3 = TriFace->Scrz[i2];
|
||||
|
||||
{
|
||||
pl_sInt32 dY = Y2-Y0;
|
||||
if (dY) {
|
||||
dX2 = (Scrx[i2] - X1) / dY;
|
||||
dZ2 = (Z3 - Z1) / dY;
|
||||
}
|
||||
dY = Y1-Y0;
|
||||
if (dY) {
|
||||
dX1 = (Scrx[i1] - X1) / dY;
|
||||
dZ1 = (Z2 - Z1) / dY;
|
||||
if (dX2 < dX1) {
|
||||
SWAP(dX1,dX2,pl_sInt32);
|
||||
SWAP(dZ1,dZ2,pl_Float);
|
||||
stat = 2;
|
||||
} else stat = 1;
|
||||
Z2 = Z1;
|
||||
} else {
|
||||
if (Scrx[i1] > X1) {
|
||||
X2 = Scrx[i1];
|
||||
stat = 2|4;
|
||||
} else {
|
||||
X1 = Scrx[i1];
|
||||
SWAP(Z1,Z2,pl_Float);
|
||||
stat = 1|8;
|
||||
}
|
||||
}
|
||||
|
||||
if (zbuf)
|
||||
{
|
||||
pl_sInt32 tmp=(dX1-dX2)*dY;
|
||||
if (tmp) dZL = ((dZ1-dZ2)*dY)*(double)(1<<XPOS_BITS)/(double)tmp;
|
||||
else {
|
||||
tmp = X2-X1;
|
||||
if (tmp) dZL = (Z2-Z1)*(double)(1<<XPOS_BITS)/tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gmem += (Y0 * swidth);
|
||||
zbuf += (Y0 * zfb_width);
|
||||
|
||||
while (Y0 < Y2) {
|
||||
if (Y0 == Y1) {
|
||||
pl_sInt32 dY = Y2 - Scry[i1];
|
||||
if (dY) {
|
||||
DO_STAT_XDELTAS
|
||||
dZ1 = (Z3-Z1)/dY;
|
||||
}
|
||||
}
|
||||
pl_sInt32 XL1 = (X1+(1<<(XPOS_BITS-1)))>>XPOS_BITS;
|
||||
pl_sInt32 XL2 = ((X2+(1<<(XPOS_BITS-1)))>>XPOS_BITS) - XL1;
|
||||
if (XL2 > 0) {
|
||||
gmem += XL1;
|
||||
XL1 += XL2;
|
||||
if (zbuf)
|
||||
{
|
||||
pl_Float ZL = Z1;
|
||||
zbuf += XL1-XL2;
|
||||
do {
|
||||
if (*zbuf < ZL) {
|
||||
if (zb_update) *zbuf = (pl_ZBuffer) ZL;
|
||||
Comb::doPix((LICE_pixel_chan *)gmem,col0,col1,col2,255,alpha);
|
||||
}
|
||||
gmem++;
|
||||
zbuf++;
|
||||
ZL += dZL;
|
||||
} while (--XL2);
|
||||
zbuf -= XL1;
|
||||
}
|
||||
else
|
||||
{
|
||||
do {
|
||||
Comb::doPix((LICE_pixel_chan *)gmem,col0,col1,col2,255,alpha);
|
||||
gmem++;
|
||||
} while (--XL2);
|
||||
}
|
||||
gmem -= XL1;
|
||||
|
||||
}
|
||||
gmem += swidth;
|
||||
zbuf += zfb_width;
|
||||
Z1 += dZ1;
|
||||
X1 += dX1;
|
||||
X2 += dX2;
|
||||
Y0++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
void pl_Cam::PutFace(pl_Face *TriFace)
|
||||
{
|
||||
LICE_pixel *gmem = m_fBuffer.m_buf;
|
||||
if (WDL_NOT_NORMALLY(!gmem)) return;
|
||||
|
||||
int zfb_width = 0;
|
||||
int zBufferable = TriFace->Material->zBufferable;
|
||||
pl_ZBuffer *zb = NULL;
|
||||
if (zBufferable &&
|
||||
zBuffer.GetSize() &&
|
||||
WDL_NORMALLY(zBuffer.GetSize() >= m_fBuffer.m_w*m_fBuffer.m_h)
|
||||
)
|
||||
{
|
||||
zfb_width = m_fBuffer.m_w;
|
||||
zb = zBuffer.Get();
|
||||
}
|
||||
|
||||
int swidth = m_fBuffer.m_span;
|
||||
if (m_fBuffer.m_flipped)
|
||||
{
|
||||
gmem += swidth*(m_fBuffer.m_h-1);
|
||||
swidth=-swidth;
|
||||
}
|
||||
|
||||
pl_Mat *mat=TriFace->Material;
|
||||
|
||||
#ifndef PLUSH_NO_MULTITEXTURE
|
||||
|
||||
#ifndef PLUSH_NO_TEXTURE
|
||||
if (mat->Texture&&mat->Texture2)
|
||||
#else
|
||||
#ifndef PLUSH_NO_SOLIDGOURAUD
|
||||
if (mat->Texture||mat->Texture2)
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
pl_Float texsc[4];
|
||||
memcpy(texsc,mat->TexScaling,sizeof(mat->TexScaling));
|
||||
memcpy(texsc+2,mat->Tex2Scaling,sizeof(mat->Tex2Scaling));
|
||||
int tidx = mat->TexMapIdx;
|
||||
if (tidx<0 || tidx>=PLUSH_MAX_MAPCOORDS)tidx=PLUSH_MAX_MAPCOORDS-1;
|
||||
int tidx2 = mat->Tex2MapIdx;
|
||||
if (tidx2<0 || tidx2>=PLUSH_MAX_MAPCOORDS)tidx2=PLUSH_MAX_MAPCOORDS-1;
|
||||
|
||||
PLMTexTri(gmem,swidth,TriFace,zb,zfb_width,zBufferable!=2,(int) (mat->SolidOpacity*256.0),mat->SolidCombineMode,
|
||||
mat->Texture,texsc,(int) (mat->TexOpacity*256.0),mat->TexCombineMode,tidx,
|
||||
mat->Texture2,(int) (mat->Tex2Opacity*256.0),mat->Tex2CombineMode,tidx2
|
||||
);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef PLUSH_NO_TEXTURE
|
||||
#ifndef PLUSH_NO_SOLIDGOURAUD
|
||||
if (mat->Texture||mat->Texture2)
|
||||
#endif
|
||||
{
|
||||
LICE_IBitmap *tex=mat->Texture ? mat->Texture : mat->Texture2;
|
||||
int talpha = (int) (mat->Texture ? mat->TexOpacity*256.0 : mat->Tex2Opacity*256.0);
|
||||
int tcomb = (int) (mat->Texture ? mat->TexCombineMode : mat->Tex2CombineMode);
|
||||
int tidx = (mat->Texture ? mat->TexMapIdx: mat->Tex2MapIdx);
|
||||
if (tidx<0 || tidx>=PLUSH_MAX_MAPCOORDS)tidx=PLUSH_MAX_MAPCOORDS-1;
|
||||
pl_Float texsc[2];
|
||||
memcpy(texsc,mat->Texture ? mat->TexScaling : mat->Tex2Scaling,sizeof(texsc));
|
||||
PLTexTri(gmem,swidth,TriFace,zb,zfb_width,zBufferable!=2,(int) (mat->SolidOpacity*256.0),mat->SolidCombineMode,tex,texsc,talpha,tcomb,tidx);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int alpha=(int) (mat->SolidOpacity*256.0);
|
||||
if (!alpha) return;
|
||||
|
||||
#ifndef PLUSH_NO_SOLIDGOURAUD
|
||||
#ifndef PLUSH_NO_SOLIDFLAT
|
||||
if (mat->Smoothing)
|
||||
#endif
|
||||
{
|
||||
#define __LICE__ACTION(comb) PLSolidPutFace<comb>::SolidGouraud(gmem,swidth,TriFace,alpha,zb,zfb_width, zBufferable!=2);
|
||||
__LICE_ACTION_CONSTANTALPHA(mat->SolidCombineMode,alpha,true);
|
||||
#undef __LICE__ACTION
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PLUSH_NO_SOLIDFLAT
|
||||
|
||||
#define __LICE__ACTION(comb) PLSolidPutFace<comb>::Solid(gmem,swidth,TriFace,alpha,zb,zfb_width, zBufferable!=2);
|
||||
__LICE_ACTION_CONSTANTALPHA(mat->SolidCombineMode,alpha,true);
|
||||
#undef __LICE__ACTION
|
||||
|
||||
#endif // PLUSH_NO_SOLIDFLAT
|
||||
}
|
||||
|
||||
|
||||
347
oversampling/WDL/plush2/pl_read_3ds.cpp
Normal file
347
oversampling/WDL/plush2/pl_read_3ds.cpp
Normal file
@@ -0,0 +1,347 @@
|
||||
/******************************************************************************
|
||||
Plush Version 1.2
|
||||
read_3ds.c
|
||||
3DS Object Reader
|
||||
Copyright (c) 1996-2000, Justin Frankel
|
||||
******************************************************************************/
|
||||
|
||||
#include "plush.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pl_uInt16 id;
|
||||
void (*func)(pl_uChar *ptr, pl_uInt32 p);
|
||||
} _pl_3DSChunk;
|
||||
|
||||
static pl_Obj *obj;
|
||||
static pl_Obj *bobj;
|
||||
static pl_Obj *lobj;
|
||||
static pl_sInt16 currentobj;
|
||||
static pl_Mat *_m;
|
||||
|
||||
static pl_Float _pl3DSReadFloat(pl_uChar **ptr);
|
||||
static pl_uInt32 _pl3DSReadDWord(pl_uChar **ptr);
|
||||
static pl_uInt16 _pl3DSReadWord(pl_uChar **ptr);
|
||||
static void _pl3DSChunkReader(pl_uChar *ptr, int len);
|
||||
static void _pl3DSRGBFReader(pl_uChar *f, pl_uInt32 p);
|
||||
static void _pl3DSRGBBReader(pl_uChar *f, pl_uInt32 p);
|
||||
static int _pl3DSASCIIZReader(pl_uChar *ptr, pl_uInt32 p, char *as);
|
||||
static void _pl3DSObjBlockReader(pl_uChar *ptr, pl_uInt32 p);
|
||||
static void _pl3DSTriMeshReader(pl_uChar *f, pl_uInt32 p);
|
||||
static void _pl3DSVertListReader(pl_uChar *f, pl_uInt32 p);
|
||||
static void _pl3DSFaceListReader(pl_uChar *f, pl_uInt32 p);
|
||||
static void _pl3DSFaceMatReader(pl_uChar *f, pl_uInt32 p);
|
||||
static void MapListReader(pl_uChar *f, pl_uInt32 p);
|
||||
static pl_sInt16 _pl3DSFindChunk(pl_uInt16 id);
|
||||
|
||||
static _pl_3DSChunk _pl3DSChunkNames[] = {
|
||||
{0x4D4D,NULL}, /* Main */
|
||||
{0x3D3D,NULL}, /* Object Mesh */
|
||||
{0x4000,_pl3DSObjBlockReader},
|
||||
{0x4100,_pl3DSTriMeshReader},
|
||||
{0x4110,_pl3DSVertListReader},
|
||||
{0x4120,_pl3DSFaceListReader},
|
||||
{0x4130,_pl3DSFaceMatReader},
|
||||
{0x4140,MapListReader},
|
||||
{0xAFFF,NULL}, /* Material */
|
||||
{0xA010,NULL}, /* Ambient */
|
||||
{0xA020,NULL}, /* Diff */
|
||||
{0xA030,NULL}, /* Specular */
|
||||
{0xA200,NULL}, /* Texture */
|
||||
{0x0010,_pl3DSRGBFReader},
|
||||
{0x0011,_pl3DSRGBBReader},
|
||||
};
|
||||
|
||||
pl_Obj *plRead3DSObjFromFile(char *fn, pl_Mat *m)
|
||||
{
|
||||
FILE *f = fopen(fn, "rb");
|
||||
if (!f) return 0;
|
||||
fseek(f, 0, 2);
|
||||
pl_uInt32 p = ftell(f);
|
||||
rewind(f);
|
||||
|
||||
WDL_HeapBuf buf;
|
||||
buf.Resize(p);
|
||||
int s = fread(buf.Get(), 1, p, f);
|
||||
fclose(f);
|
||||
|
||||
if(!s) return 0;
|
||||
|
||||
return plRead3DSObj(buf.Get(), s, m);
|
||||
}
|
||||
|
||||
pl_Obj *plRead3DSObjFromResource(HINSTANCE hInst, int resid, pl_Mat *m)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(resid), "3DS");
|
||||
if(!hResource) return NULL;
|
||||
|
||||
DWORD imageSize = SizeofResource(hInst, hResource);
|
||||
if(imageSize < 6) return NULL;
|
||||
|
||||
HGLOBAL res = LoadResource(hInst, hResource);
|
||||
const void* pResourceData = LockResource(res);
|
||||
if(!pResourceData) return NULL;
|
||||
|
||||
unsigned char *data = (unsigned char *)pResourceData;
|
||||
|
||||
pl_Obj *o = plRead3DSObj(data, imageSize, m);
|
||||
|
||||
DeleteObject(res);
|
||||
|
||||
return o;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
pl_Obj *plRead3DSObj(void *ptr, int size, pl_Mat *m)
|
||||
{
|
||||
_m = m;
|
||||
obj = bobj = lobj = 0;
|
||||
currentobj = 0;
|
||||
|
||||
_pl3DSChunkReader((pl_uChar *)ptr, size);
|
||||
|
||||
return bobj;
|
||||
}
|
||||
|
||||
static pl_Float _pl3DSReadFloat(pl_uChar **ptr) {
|
||||
pl_uInt32 *i;
|
||||
pl_IEEEFloat32 c;
|
||||
i = (pl_uInt32 *) &c;
|
||||
*i = _pl3DSReadDWord(ptr);
|
||||
return ((pl_Float) c);
|
||||
}
|
||||
|
||||
static pl_uInt32 _pl3DSReadDWord(pl_uChar **ptr)
|
||||
{
|
||||
pl_uInt32 r;
|
||||
pl_uChar *p = *ptr;
|
||||
r = *p++;
|
||||
r |= (*p++)<<8;
|
||||
r |= (*p++)<<16;
|
||||
r |= (*p++)<<24;
|
||||
*ptr += 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
static pl_uInt16 _pl3DSReadWord(pl_uChar **ptr)
|
||||
{
|
||||
pl_uInt16 r;
|
||||
pl_uChar *p = *ptr;
|
||||
r = *p++;
|
||||
r |= (*p++)<<8;
|
||||
*ptr += 2;
|
||||
return r;
|
||||
}
|
||||
|
||||
static void _pl3DSRGBFReader(pl_uChar *f, pl_uInt32 p)
|
||||
{
|
||||
pl_Float c[3];
|
||||
if(p < 3*4) return;
|
||||
c[0] = _pl3DSReadFloat(&f);
|
||||
c[1] = _pl3DSReadFloat(&f);
|
||||
c[2] = _pl3DSReadFloat(&f);
|
||||
}
|
||||
|
||||
static void _pl3DSRGBBReader(pl_uChar *f, pl_uInt32 p)
|
||||
{
|
||||
unsigned char c[3];
|
||||
if(p < 3) return;
|
||||
memcpy(c, f, sizeof(c));
|
||||
}
|
||||
|
||||
static int _pl3DSASCIIZReader(pl_uChar *ptr, pl_uInt32 p, char *as)
|
||||
{
|
||||
int l = 0;
|
||||
while (*ptr && p>0)
|
||||
{
|
||||
if(as) *as++ = *ptr;
|
||||
ptr++;
|
||||
l++;
|
||||
p--;
|
||||
}
|
||||
if(as) *as = 0;
|
||||
return l+1;
|
||||
}
|
||||
|
||||
static void _pl3DSObjBlockReader(pl_uChar *ptr, pl_uInt32 p)
|
||||
{
|
||||
int l = _pl3DSASCIIZReader(ptr, p, 0);
|
||||
ptr += l;
|
||||
p -= l;
|
||||
_pl3DSChunkReader(ptr, p);
|
||||
}
|
||||
|
||||
static void _pl3DSTriMeshReader(pl_uChar *ptr, pl_uInt32 p)
|
||||
{
|
||||
pl_uInt32 i;
|
||||
pl_Face *face;
|
||||
obj = new pl_Obj;
|
||||
_pl3DSChunkReader(ptr, p);
|
||||
i = obj->Faces.GetSize();
|
||||
face = obj->Faces.Get();
|
||||
while (i--)
|
||||
{
|
||||
pl_Vertex *vp=obj->Vertices.Get();
|
||||
pl_Vertex *fVertices[3] = {
|
||||
vp+face->VertexIndices[0],
|
||||
vp+face->VertexIndices[1],
|
||||
vp+face->VertexIndices[2],
|
||||
};
|
||||
face->MappingU[0][0] = fVertices[0]->xformedx;
|
||||
face->MappingV[0][0] = fVertices[0]->xformedy;
|
||||
face->MappingU[0][1] = fVertices[1]->xformedx;
|
||||
face->MappingV[0][1] = fVertices[1]->xformedy;
|
||||
face->MappingU[0][2] = fVertices[2]->xformedx;
|
||||
face->MappingV[0][2] = fVertices[2]->xformedy;
|
||||
face++;
|
||||
}
|
||||
obj->CalculateNormals();
|
||||
if (currentobj == 0)
|
||||
{
|
||||
currentobj = 1;
|
||||
lobj = bobj = obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
lobj->Children.Add(obj);
|
||||
lobj = obj;
|
||||
}
|
||||
}
|
||||
|
||||
static void _pl3DSVertListReader(pl_uChar *f, pl_uInt32 p)
|
||||
{
|
||||
pl_uInt16 nv;
|
||||
pl_Vertex *v;
|
||||
int len = (int)p;
|
||||
nv = _pl3DSReadWord(&f);
|
||||
len -= 2;
|
||||
if(len <= 0) return;
|
||||
obj->Vertices.Resize(nv);
|
||||
v = obj->Vertices.Get();
|
||||
while (nv--)
|
||||
{
|
||||
memset(v,0,sizeof(pl_Vertex));
|
||||
v->x = _pl3DSReadFloat(&f);
|
||||
v->y = _pl3DSReadFloat(&f);
|
||||
v->z = _pl3DSReadFloat(&f);
|
||||
len -= 3*4;
|
||||
if(len < 0) return;
|
||||
v++;
|
||||
}
|
||||
}
|
||||
|
||||
static void _pl3DSFaceListReader(pl_uChar *f, pl_uInt32 p)
|
||||
{
|
||||
pl_uInt16 nv;
|
||||
pl_uInt16 c[3];
|
||||
pl_uInt16 flags;
|
||||
pl_Face *face;
|
||||
int len = (int)p;
|
||||
|
||||
nv = _pl3DSReadWord(&f);
|
||||
len -= 2;
|
||||
if(len <= 0) return;
|
||||
obj->Faces.Resize(nv);
|
||||
face = obj->Faces.Get();
|
||||
while (nv--)
|
||||
{
|
||||
memset(face,0,sizeof(pl_Face));
|
||||
c[0] = _pl3DSReadWord(&f);
|
||||
c[1] = _pl3DSReadWord(&f);
|
||||
c[2] = _pl3DSReadWord(&f);
|
||||
flags = _pl3DSReadWord(&f);
|
||||
len -= 4*2;
|
||||
if(len < 0) return;
|
||||
|
||||
face->VertexIndices[0] = (c[0]&0x0000FFFF);
|
||||
face->VertexIndices[1] = (c[1]&0x0000FFFF);
|
||||
face->VertexIndices[2] = (c[2]&0x0000FFFF);
|
||||
face->Material = _m;
|
||||
face++;
|
||||
}
|
||||
if(len) _pl3DSChunkReader(f, len);
|
||||
}
|
||||
|
||||
static void _pl3DSFaceMatReader(pl_uChar *ptr, pl_uInt32 p)
|
||||
{
|
||||
pl_uInt16 n, nf;
|
||||
|
||||
int l = _pl3DSASCIIZReader(ptr, p, 0);
|
||||
ptr += l;
|
||||
p -= l;
|
||||
|
||||
n = _pl3DSReadWord(&ptr);
|
||||
while (n--)
|
||||
{
|
||||
nf = _pl3DSReadWord(&ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static void MapListReader(pl_uChar *f, pl_uInt32 p)
|
||||
{
|
||||
pl_uInt16 nv;
|
||||
pl_Float c[2];
|
||||
pl_Vertex *v;
|
||||
int len = (int) p;
|
||||
nv = _pl3DSReadWord(&f);
|
||||
len -= 2;
|
||||
v = obj->Vertices.Get();
|
||||
if (nv == obj->Vertices.GetSize()) while (nv--)
|
||||
{
|
||||
c[0] = _pl3DSReadFloat(&f);
|
||||
c[1] = _pl3DSReadFloat(&f);
|
||||
len -= 2*4;
|
||||
if (len < 0) return;
|
||||
v->xformedx = c[0];
|
||||
v->xformedy = c[1];
|
||||
v++;
|
||||
}
|
||||
}
|
||||
|
||||
static pl_sInt16 _pl3DSFindChunk(pl_uInt16 id)
|
||||
{
|
||||
pl_sInt16 i;
|
||||
for (i = 0; i < sizeof(_pl3DSChunkNames)/sizeof(_pl3DSChunkNames[0]); i++)
|
||||
if (id == _pl3DSChunkNames[i].id) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void _pl3DSChunkReader(pl_uChar *ptr, int len)
|
||||
{
|
||||
pl_uInt32 hlen;
|
||||
pl_uInt16 hid;
|
||||
pl_sInt16 n;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
hid = _pl3DSReadWord(&ptr);
|
||||
len -= 2;
|
||||
if(len <= 0) return;
|
||||
hlen = _pl3DSReadDWord(&ptr);
|
||||
len -= 4;
|
||||
if(len <= 0) return;
|
||||
if (hlen == 0) return;
|
||||
hlen -= 6;
|
||||
n = _pl3DSFindChunk(hid);
|
||||
if (n < 0)
|
||||
{
|
||||
ptr += hlen;
|
||||
len -= hlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
pl_uChar *p = ptr;
|
||||
if (_pl3DSChunkNames[n].func != NULL)
|
||||
_pl3DSChunkNames[n].func(p, hlen);
|
||||
else
|
||||
_pl3DSChunkReader(p, hlen);
|
||||
|
||||
ptr += hlen;
|
||||
len -= hlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
181
oversampling/WDL/plush2/pl_read_cob.cpp
Normal file
181
oversampling/WDL/plush2/pl_read_cob.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/******************************************************************************
|
||||
Plush Version 1.2
|
||||
read_cob.c
|
||||
ASCII COB Object Reader
|
||||
Copyright (c) 1996-2000, Justin Frankel
|
||||
******************************************************************************/
|
||||
|
||||
#include "plush.h"
|
||||
|
||||
#define PL_COB_MAX_LINELENGTH 1024
|
||||
|
||||
pl_Obj *plReadCOBObj(char *fn, pl_Mat *mat) {
|
||||
FILE *fp = fopen(fn,"rt");
|
||||
int p1,m1,p2,m2,p3,m3;
|
||||
char temp_string[PL_COB_MAX_LINELENGTH];
|
||||
float TransMatrix[4][4];
|
||||
pl_Obj *obj;
|
||||
pl_sInt32 x,i2;
|
||||
int numVertices, numMappingVertices, numFaces, i;
|
||||
pl_Float *MappingVertices = 0;
|
||||
if (!fp) return 0;
|
||||
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
if (memcmp("Caligari",temp_string,8)) { fclose(fp); return 0; }
|
||||
|
||||
do {
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
} while (!feof(fp) && memcmp("Transform",temp_string,9));
|
||||
if (feof(fp)) { fclose(fp); return 0; }
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
sscanf(temp_string,"%f %f %f %f",
|
||||
&TransMatrix[0][0],&TransMatrix[0][1],&TransMatrix[0][2],&TransMatrix[0][3]);
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
sscanf(temp_string,"%f %f %f %f",
|
||||
&TransMatrix[1][0],&TransMatrix[1][1],&TransMatrix[1][2],&TransMatrix[1][3]);
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
sscanf(temp_string,"%f %f %f %f",
|
||||
&TransMatrix[2][0],&TransMatrix[2][1],&TransMatrix[2][2],&TransMatrix[2][3]);
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
sscanf(temp_string,"%f %f %f %f",
|
||||
&TransMatrix[3][0],&TransMatrix[3][1],&TransMatrix[3][2],&TransMatrix[3][3]);
|
||||
|
||||
do {
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
} while (!feof(fp) && memcmp("World Vertices",temp_string,12));
|
||||
if (feof(fp) || sscanf(temp_string,"World Vertices %d",&numVertices) != 1)
|
||||
{ fclose(fp); return 0; }
|
||||
|
||||
rewind(fp);
|
||||
do {
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
} while (!feof(fp) && memcmp("Texture Vertices",temp_string,16));
|
||||
if (feof(fp) ||
|
||||
sscanf(temp_string,"Texture Vertices %d",&numMappingVertices) != 1) {
|
||||
fclose(fp); return 0;
|
||||
}
|
||||
|
||||
rewind(fp);
|
||||
do {
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
} while (!feof(fp) && memcmp("Faces",temp_string,5));
|
||||
if (feof(fp) || sscanf(temp_string,"Faces %d",&numFaces) != 1) {
|
||||
fclose(fp); return 0;
|
||||
}
|
||||
for (x = numFaces; x; x--) {
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
if (feof(fp) || sscanf(temp_string+4," verts %d",&i) != 1 || i < 3) {
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
numFaces += i-3;
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
}
|
||||
obj = new pl_Obj(numVertices,numFaces);
|
||||
if (!obj) { fclose(fp); return 0; }
|
||||
rewind(fp);
|
||||
do {
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
} while (!feof(fp) && memcmp("World Vertices",temp_string,12));
|
||||
if (feof(fp)) { delete obj; fclose(fp); return 0; }
|
||||
for (x = 0; x < numVertices; x ++) {
|
||||
float xp, yp, zp;
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
if (feof(fp) ||
|
||||
sscanf(temp_string,"%f %f %f", &xp, &yp, &zp) != 3) {
|
||||
delete obj; fclose(fp); return 0;
|
||||
}
|
||||
obj->Vertices.Get()[x].x = (TransMatrix[0][0]*xp+TransMatrix[0][1]*yp+
|
||||
TransMatrix[0][2]*zp+TransMatrix[0][3]);
|
||||
obj->Vertices.Get()[x].y = (TransMatrix[1][0]*xp+TransMatrix[1][1]*yp+
|
||||
TransMatrix[1][2]*zp+TransMatrix[1][3]);
|
||||
obj->Vertices.Get()[x].z = (TransMatrix[2][0]*xp+TransMatrix[2][1]*yp+
|
||||
TransMatrix[2][2]*zp+TransMatrix[2][3]);
|
||||
}
|
||||
rewind(fp);
|
||||
do {
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
} while (!feof(fp) && memcmp("Texture Vertices",temp_string,16));
|
||||
if (!feof(fp)) {
|
||||
MappingVertices = (pl_Float *)
|
||||
malloc(sizeof(pl_Float ) * numMappingVertices * 2);
|
||||
if (MappingVertices) {
|
||||
for (x = 0; x < numMappingVertices; x ++) {
|
||||
float p1, p2;
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
if (feof(fp) || sscanf(temp_string,"%f %f", &p1, &p2) != 2) {
|
||||
free(MappingVertices); delete obj; fclose(fp); return 0;
|
||||
}
|
||||
MappingVertices[x*2] = p1;
|
||||
MappingVertices[x*2+1] = p2;
|
||||
}
|
||||
}
|
||||
}
|
||||
rewind(fp);
|
||||
do {
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
} while (!feof(fp) && memcmp("Faces",temp_string,5));
|
||||
if (feof(fp)) {
|
||||
if (MappingVertices) free(MappingVertices);
|
||||
delete obj; fclose(fp); return 0;
|
||||
}
|
||||
for (x = 0; x < numFaces; x ++) {
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
sscanf(temp_string+4," verts %d",&i);
|
||||
fgets(temp_string,PL_COB_MAX_LINELENGTH,fp);
|
||||
if (i == 3) {
|
||||
if (feof(fp) || sscanf(temp_string,"<%d,%d> <%d,%d> <%d,%d>",
|
||||
&p3,&m3,&p2,&m2,&p1,&m1) != 6) {
|
||||
if (MappingVertices) free(MappingVertices);
|
||||
delete obj; fclose(fp); return 0;
|
||||
}
|
||||
obj->Faces.Get()[x].VertexIndices[0] = p1;
|
||||
obj->Faces.Get()[x].VertexIndices[1] = p2;
|
||||
obj->Faces.Get()[x].VertexIndices[2] = p3;
|
||||
if (MappingVertices) {
|
||||
obj->Faces.Get()[x].MappingU[0][0] = MappingVertices[m1*2];
|
||||
obj->Faces.Get()[x].MappingV[0][0] = MappingVertices[m1*2+1];
|
||||
obj->Faces.Get()[x].MappingU[0][1] = MappingVertices[m2*2];
|
||||
obj->Faces.Get()[x].MappingV[0][1] = MappingVertices[m2*2+1];
|
||||
obj->Faces.Get()[x].MappingU[0][2] = MappingVertices[m3*2];
|
||||
obj->Faces.Get()[x].MappingV[0][2] = MappingVertices[m3*2+1];
|
||||
}
|
||||
obj->Faces.Get()[x].Material = mat;
|
||||
} else {
|
||||
int p[16],m[16];
|
||||
if (feof(fp)) {
|
||||
if (MappingVertices) free(MappingVertices);
|
||||
delete obj; fclose(fp); return 0;
|
||||
}
|
||||
sscanf(temp_string,
|
||||
"<%d,%d> <%d,%d> <%d,%d> <%d,%d> "
|
||||
"<%d,%d> <%d,%d> <%d,%d> <%d,%d> "
|
||||
"<%d,%d> <%d,%d> <%d,%d> <%d,%d> "
|
||||
"<%d,%d> <%d,%d> <%d,%d> <%d,%d> ",
|
||||
p+0,m+0,p+1,m+1,p+2,m+2,p+3,m+3,
|
||||
p+4,m+4,p+5,m+5,p+6,m+6,p+7,m+7,
|
||||
p+8,m+8,p+9,m+9,p+10,m+10,p+11,m+11,
|
||||
p+12,m+12,p+13,m+13,p+14,m+14,p+15,m+15);
|
||||
for (i2 = 1; i2 < (i-1); i2 ++) {
|
||||
obj->Faces.Get()[x].VertexIndices[0] = p[0];
|
||||
obj->Faces.Get()[x].VertexIndices[1] = p[i2+1];
|
||||
obj->Faces.Get()[x].VertexIndices[2] = p[i2];
|
||||
if (MappingVertices) {
|
||||
obj->Faces.Get()[x].MappingU[0][0] = MappingVertices[m[0]*2];
|
||||
obj->Faces.Get()[x].MappingV[0][0] = MappingVertices[m[0]*2+1];
|
||||
obj->Faces.Get()[x].MappingU[0][1] = MappingVertices[m[i2+1]*2];
|
||||
obj->Faces.Get()[x].MappingV[0][1] = MappingVertices[m[i2+1]*2+1];
|
||||
obj->Faces.Get()[x].MappingU[0][2] = MappingVertices[m[i2]*2];
|
||||
obj->Faces.Get()[x].MappingV[0][2] = MappingVertices[m[i2]*2+1];
|
||||
}
|
||||
obj->Faces.Get()[x].Material = mat;
|
||||
x++;
|
||||
}
|
||||
x--;
|
||||
}
|
||||
}
|
||||
if (MappingVertices) free(MappingVertices);
|
||||
obj->CalculateNormals();
|
||||
fclose(fp);
|
||||
return obj;
|
||||
}
|
||||
69
oversampling/WDL/plush2/pl_read_jaw.cpp
Normal file
69
oversampling/WDL/plush2/pl_read_jaw.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/******************************************************************************
|
||||
Plush Version 1.2
|
||||
read_jaw.c
|
||||
Jaw3D Object Reader
|
||||
Copyright (c) 1996-2000, Justin Frankel
|
||||
*******************************************************************************
|
||||
Notes on .JAW files:
|
||||
This is a file format created by Jawed Karim for Jaw3D
|
||||
(http://jaw3d.home.ml.org).
|
||||
-- updated 11/6/00 - www.jawed.com
|
||||
It is very simple, and lets one easily create ones own models using only
|
||||
a text editor. The format is pretty simple:
|
||||
The first line must be "Light: (x,y,z)" where x,y, and z are the x y and
|
||||
z components of the lightsource vector (I think ;)
|
||||
A series of lines, numbered 0 to n, in the format of
|
||||
"i: x y z", where i is the vertex number (which should be listed in
|
||||
order, and x y and z are the coordinates of that vertex.
|
||||
A series of lines, having the format "tri a, b, c" where a b and c are
|
||||
the vertices that the face uses. It is unclear at this time which
|
||||
way the vertices are listed (ccw or cw), so just make em consistent
|
||||
and you can always use plFlipObjectNormals() on the loaded object.
|
||||
That is it! (I told ya it was simple).
|
||||
******************************************************************************/
|
||||
|
||||
#include "plush.h"
|
||||
|
||||
pl_Obj *plReadJAWObj(char *filename, pl_Mat *m) {
|
||||
FILE *jawfile;
|
||||
pl_Obj *obj;
|
||||
pl_uInt32 i;
|
||||
pl_sInt crap;
|
||||
char line[256];
|
||||
pl_uInt32 total_points = 0, total_polys = 0;
|
||||
if ((jawfile = fopen(filename, "r")) == NULL) return 0;
|
||||
fgets(line, 256, jawfile); /* Ignores lightsource info */
|
||||
while (fgets(line, 256, jawfile) != NULL)
|
||||
if (strstr(line, ":") != NULL) total_points++;
|
||||
|
||||
rewind(jawfile); fgets(line, 256, jawfile);
|
||||
while (fgets(line, 256, jawfile) != NULL)
|
||||
if (strstr(line, "tri") != NULL) total_polys++;
|
||||
|
||||
rewind(jawfile); fgets(line, 256, jawfile);
|
||||
obj = new pl_Obj(total_points,total_polys);
|
||||
|
||||
i = 0;
|
||||
while (fgets(line, 256, jawfile) != NULL) if (strstr(line, ":") != NULL) {
|
||||
float x, y, z;
|
||||
sscanf(line, "%d: %f %f %f",&crap,&x,&y,&z);
|
||||
obj->Vertices.Get()[i].x = (pl_Float) x;
|
||||
obj->Vertices.Get()[i].y = (pl_Float) y;
|
||||
obj->Vertices.Get()[i].z = (pl_Float) z;
|
||||
i++;
|
||||
}
|
||||
rewind(jawfile); fgets(line, 256, jawfile);
|
||||
i = 0;
|
||||
while (fgets(line, 256, jawfile) != NULL) if (strstr(line, "tri") != NULL) {
|
||||
pl_uInt32 a,b,c;
|
||||
sscanf(line, "tri %ld, %ld, %ld", &a, &b, &c);
|
||||
obj->Faces.Get()[i].VertexIndices[0] = a;
|
||||
obj->Faces.Get()[i].VertexIndices[1] = c;
|
||||
obj->Faces.Get()[i].VertexIndices[2] = b;
|
||||
obj->Faces.Get()[i].Material = m;
|
||||
i++;
|
||||
}
|
||||
fclose(jawfile);
|
||||
obj->CalculateNormals();
|
||||
return obj;
|
||||
}
|
||||
50
oversampling/WDL/plush2/pl_spline.cpp
Normal file
50
oversampling/WDL/plush2/pl_spline.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/******************************************************************************
|
||||
Plush Version 1.2
|
||||
spline.c
|
||||
n-th Dimensional Spline Interpolator
|
||||
Copyright (c) 1996-2000, Justin Frankel
|
||||
******************************************************************************/
|
||||
|
||||
#include "plush.h"
|
||||
|
||||
void pl_Spline::GetPoint(pl_Float frame, pl_Float *out) {
|
||||
pl_sInt32 i, i_1, i0, i1, i2;
|
||||
pl_Float time1,time2,time3;
|
||||
pl_Float t1,t2,t3,t4,u1,u2,u3,u4,v1,v2,v3;
|
||||
pl_Float a,b,c,d;
|
||||
|
||||
int numKeys=keys.GetSize();
|
||||
pl_Float *keyptrs = keys.Get();
|
||||
|
||||
a = (1-tens)*(1+cont)*(1+bias);
|
||||
b = (1-tens)*(1-cont)*(1-bias);
|
||||
c = (1-tens)*(1-cont)*(1+bias);
|
||||
d = (1-tens)*(1+cont)*(1-bias);
|
||||
v1 = t1 = -a / 2.0; u1 = a;
|
||||
u2 = (-6-2*a+2*b+c)/2.0; v2 = (a-b)/2.0; t2 = (4+a-b-c) / 2.0;
|
||||
t3 = (-4+b+c-d) / 2.0;
|
||||
u3 = (6-2*b-c+d)/2.0;
|
||||
v3 = b/2.0;
|
||||
t4 = d/2.0; u4 = -t4;
|
||||
|
||||
i0 = (pl_uInt) frame;
|
||||
i_1 = i0 - 1;
|
||||
while (i_1 < 0) i_1 += numKeys;
|
||||
i1 = i0 + 1;
|
||||
while (i1 >= numKeys) i1 -= numKeys;
|
||||
i2 = i0 + 2;
|
||||
while (i2 >= numKeys) i2 -= numKeys;
|
||||
time1 = frame - (pl_Float) ((pl_uInt) frame);
|
||||
time2 = time1*time1;
|
||||
time3 = time2*time1;
|
||||
i0 *= keyWidth;
|
||||
i1 *= keyWidth;
|
||||
i2 *= keyWidth;
|
||||
i_1 *= keyWidth;
|
||||
for (i = 0; i < keyWidth; i ++) {
|
||||
a = t1*keyptrs[i+i_1]+t2*keyptrs[i+i0]+t3*keyptrs[i+i1]+t4*keyptrs[i+i2];
|
||||
b = u1*keyptrs[i+i_1]+u2*keyptrs[i+i0]+u3*keyptrs[i+i1]+u4*keyptrs[i+i2];
|
||||
c = v1*keyptrs[i+i_1]+v2*keyptrs[i+i0]+v3*keyptrs[i+i1];
|
||||
*out++ = a*time3 + b*time2 + c*time1 + keyptrs[i+i0];
|
||||
}
|
||||
}
|
||||
607
oversampling/WDL/plush2/plush.h
Normal file
607
oversampling/WDL/plush2/plush.h
Normal file
@@ -0,0 +1,607 @@
|
||||
/******************************************************************************
|
||||
plush.h
|
||||
PLUSH 3D VERSION 2.0 MAIN HEADER
|
||||
Copyright (c) 1996-2000 Justin Frankel
|
||||
Copyright (c) 1998-2000 Nullsoft, Inc.
|
||||
Copyright (c) 2008 Cockos Incorporated
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _PLUSH_H_
|
||||
#define _PLUSH_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "../lice/lice.h" // using LICE for images
|
||||
#include "../ptrlist.h"
|
||||
#include "../wdltypes.h"
|
||||
|
||||
typedef float pl_ZBuffer; /* z-buffer type (must be float) */
|
||||
typedef double pl_Float; /* General floating point */
|
||||
typedef float pl_IEEEFloat32; /* IEEE 32 bit floating point */
|
||||
typedef signed int pl_sInt32; /* signed 32 bit integer */
|
||||
typedef unsigned int pl_uInt32; /* unsigned 32 bit integer */
|
||||
typedef signed short int pl_sInt16; /* signed 16 bit integer */
|
||||
typedef unsigned short int pl_uInt16; /* unsigned 16 bit integer */
|
||||
typedef signed int pl_sInt; /* signed optimal integer */
|
||||
typedef unsigned int pl_uInt; /* unsigned optimal integer */
|
||||
typedef bool pl_Bool; /* boolean */
|
||||
typedef unsigned char pl_uChar; /* unsigned 8 bit integer */
|
||||
typedef signed char pl_sChar; /* signed 8 bit integer */
|
||||
|
||||
|
||||
|
||||
/* pi! */
|
||||
#define PL_PI 3.141592653589793238
|
||||
|
||||
/* Utility min() and max() functions */
|
||||
#define plMin(x,y) (( ( x ) > ( y ) ? ( y ) : ( x )))
|
||||
#define plMax(x,y) (( ( x ) < ( y ) ? ( y ) : ( x )))
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Light modes. Used with plLight.Type or plLightSet().
|
||||
** Note that PL_LIGHT_POINT_ANGLE assumes no falloff and uses the angle between
|
||||
** the light and the point, PL_LIGHT_POINT_DISTANCE has falloff with proportion
|
||||
** to distance**2 (see plLightSet() for setting it), PL_LIGHT_POINT does both.
|
||||
*/
|
||||
#define PL_LIGHT_NONE (0x0)
|
||||
#define PL_LIGHT_VECTOR (0x1)
|
||||
#define PL_LIGHT_POINT (0x2|0x4)
|
||||
#define PL_LIGHT_POINT_DISTANCE (0x2)
|
||||
#define PL_LIGHT_POINT_ANGLE (0x4)
|
||||
|
||||
|
||||
#define PLUSH_MAX_MAPCOORDS 3 // 2 + envmap slot
|
||||
|
||||
|
||||
class pl_Mat
|
||||
{
|
||||
public:
|
||||
pl_Mat()
|
||||
{
|
||||
memset(Ambient,0,sizeof(Ambient));
|
||||
Diffuse[0]=Diffuse[1]=Diffuse[2]=1.0;
|
||||
SolidOpacity=1.0;
|
||||
SolidCombineMode= LICE_BLIT_MODE_COPY;
|
||||
|
||||
Texture=NULL;
|
||||
TexCombineMode = LICE_BLIT_MODE_ADD; //LICE_BLIT_USE_SOURCE_ALPHA?
|
||||
TexOpacity=1.0;
|
||||
TexScaling[0]=TexScaling[1]=1.0;
|
||||
TexMapIdx=0;
|
||||
|
||||
Texture2=NULL;
|
||||
Tex2CombineMode = LICE_BLIT_MODE_ADD;
|
||||
Tex2Opacity=1.0;
|
||||
Tex2Scaling[0]=Tex2Scaling[1]=1.0;
|
||||
Tex2MapIdx=-1;
|
||||
|
||||
FadeDist=0.0;
|
||||
Smoothing=Lightable=true;
|
||||
zBufferable=1;
|
||||
PerspectiveCorrect=16;
|
||||
BackfaceCull=true;
|
||||
BackfaceIllumination=0.0;
|
||||
|
||||
cachedTexture=cachedTexture2=0;
|
||||
cachesInvalid=true;
|
||||
}
|
||||
|
||||
~pl_Mat()
|
||||
{
|
||||
delete cachedTexture;
|
||||
delete cachedTexture2;
|
||||
}
|
||||
|
||||
|
||||
pl_Bool Smoothing; // smoothing of lighting
|
||||
pl_Bool Lightable; // affected by lights
|
||||
pl_uChar zBufferable; /* Can this material be Z-buffered? 2=yes, but does not update Z buffer */
|
||||
pl_uChar PerspectiveCorrect; /* Correct texture perspective every n pixels */
|
||||
|
||||
pl_Float FadeDist WDL_FIXALIGN; /* For distance fading, distance at which intensity is 0. set to 0.0 for no distance shading */
|
||||
|
||||
pl_Bool BackfaceCull; /* Are backfacing polys drawn? */
|
||||
pl_Float BackfaceIllumination WDL_FIXALIGN; /* Illuminated by lights behind them, and by how much of a factor? */
|
||||
|
||||
// colors
|
||||
pl_Float Ambient[3]; /* RGB of surface (0-1 is a good range) */
|
||||
pl_Float Diffuse[3]; /* RGB of diffuse (0-1 is a good range) */
|
||||
pl_Float SolidOpacity;
|
||||
int SolidCombineMode; /* LICE combine mode for first pass (color), default should be replace (or add-black for transparent) */
|
||||
|
||||
// textures
|
||||
LICE_IBitmap *Texture; /* Texture map (not owned by Material but a reference)*/
|
||||
pl_Float TexScaling[2] WDL_FIXALIGN; /* Texture map scaling */
|
||||
pl_Float TexOpacity;
|
||||
int TexCombineMode; /* Texture combine mode (generally should be additive) */
|
||||
int TexMapIdx; // -1 for env
|
||||
|
||||
LICE_IBitmap *Texture2;
|
||||
pl_Float Tex2Scaling[2] WDL_FIXALIGN;
|
||||
pl_Float Tex2Opacity;
|
||||
int Tex2CombineMode;
|
||||
int Tex2MapIdx; // -1 for env
|
||||
|
||||
|
||||
void InvalidateTextureCaches() { cachesInvalid=true; } // call this if you change Texture or Texture2 after rendering
|
||||
|
||||
private:
|
||||
bool cachesInvalid;
|
||||
LICE_IBitmap *cachedTexture,*cachedTexture2; // these may need to be LICE_GL_MemBitmaps etc
|
||||
|
||||
} WDL_FIXALIGN;
|
||||
|
||||
|
||||
struct pl_Vertex {
|
||||
pl_Float x, y, z; /* Vertex coordinate (objectspace) */
|
||||
pl_Float nx, ny, nz; /* Unit vertex normal (objectspace) */
|
||||
|
||||
pl_Float xformedx, xformedy, xformedz; /* Transformed vertex coordinate (cameraspace) */
|
||||
pl_Float xformednx, xformedny, xformednz; /* Transformed unit vertex normal (cameraspace) */
|
||||
};
|
||||
|
||||
struct pl_Face {
|
||||
pl_Mat *Material; /* Material of triangle */
|
||||
int VertexIndices[3]; /* Vertices of triangle */
|
||||
|
||||
pl_Float nx WDL_FIXALIGN;
|
||||
pl_Float ny;
|
||||
pl_Float nz; /* Normal of triangle (object space) */
|
||||
|
||||
pl_Float MappingU[PLUSH_MAX_MAPCOORDS][3], MappingV[PLUSH_MAX_MAPCOORDS][3]; /* Texture mapping coordinates */
|
||||
|
||||
pl_Float sLighting[3]; /* Face static lighting. Should usually be 0.0 */
|
||||
pl_Float vsLighting[3][3]; /* Vertex static lighting. Should usually be 0.0 */
|
||||
|
||||
|
||||
// calculated:
|
||||
pl_Float Shades[3][3]; /* colors (first 3 used for flat, all for Gouraud) */
|
||||
pl_Float Scrx[3], Scry[3]; /* Projected screen coordinates */
|
||||
pl_Float Scrz[3]; /* Projected 1/Z coordinates */
|
||||
|
||||
};
|
||||
|
||||
|
||||
class pl_Obj {
|
||||
public:
|
||||
pl_Obj(int nv=0, int nf=0)
|
||||
{
|
||||
if (nv) memset(Vertices.Resize(nv),0,nv*sizeof(pl_Vertex));
|
||||
if (nf) memset(Faces.Resize(nf),0,nf*sizeof(pl_Face));
|
||||
|
||||
GenMatrix=true;
|
||||
Xp=Yp=Zp=Xa=Ya=Za=0.0;
|
||||
}
|
||||
~pl_Obj() { Children.Empty(true); }
|
||||
|
||||
pl_Obj *Clone();
|
||||
void Scale(pl_Float sc);
|
||||
void Stretch(pl_Float x, pl_Float y, pl_Float z); // scales but preserves normals
|
||||
void Translate(pl_Float x, pl_Float y, pl_Float z);
|
||||
void FlipNormals();
|
||||
|
||||
void SetMaterial(pl_Mat *m, pl_Bool recurse=true);
|
||||
void CalculateNormals();
|
||||
|
||||
|
||||
pl_Float Xp, Yp, Zp, Xa, Ya, Za; /* Position and rotation of object:
|
||||
Note: rotations are around X then Y then Z. Measured in degrees */
|
||||
pl_Float Matrix[16]; /* Transformation matrix */
|
||||
pl_Float RotMatrix[16]; /* Rotation-only, for normals */
|
||||
|
||||
WDL_TypedBuf<pl_Vertex> Vertices;
|
||||
WDL_TypedBuf<pl_Face> Faces;
|
||||
WDL_PtrList<pl_Obj> Children;
|
||||
|
||||
pl_Bool GenMatrix; /* Generate Matrix from X-Z* if set */
|
||||
};
|
||||
|
||||
|
||||
class pl_Spline {
|
||||
public:
|
||||
pl_Spline() { cont=1.0; bias=0.3; tens=0.3; keyWidth=1; }
|
||||
~pl_Spline () { }
|
||||
void GetPoint(pl_Float frame, pl_Float *out);
|
||||
WDL_TypedBuf<pl_Float> keys; /* Key data, keyWidth*numKeys */
|
||||
pl_sInt keyWidth; /* Number of floats per key */
|
||||
|
||||
pl_Float cont WDL_FIXALIGN; /* Continuity. Should be -1.0 -> 1.0 */
|
||||
pl_Float bias; /* Bias. -1.0 -> 1.0 */
|
||||
pl_Float tens; /* Tension. -1.0 -> 1.0 */
|
||||
};
|
||||
|
||||
|
||||
class pl_Light {
|
||||
public:
|
||||
pl_Light() { Type = PL_LIGHT_VECTOR; Xp=Yp=0.0; Zp=1.0; Intensity[0]=Intensity[1]=Intensity[2]=1.0; }
|
||||
~pl_Light() { }
|
||||
|
||||
/*
|
||||
Set() sets up a light:
|
||||
mode: the mode of the light (PL_LIGHT_*)
|
||||
x,y,z: either the position of the light (PL_LIGHT_POINT*) or the angle
|
||||
in degrees of the light (PL_LIGHT_VECTOR)
|
||||
intensity: the intensity of the light (0.0-1.0)
|
||||
halfDist: the distance at which PL_LIGHT_POINT_DISTANCE is 1/2 intensity
|
||||
*/
|
||||
void Set(pl_uChar mode, pl_Float x, pl_Float y, pl_Float z, pl_Float intensity_r, pl_Float intensity_g, pl_Float intensity_b, pl_Float halfDist);
|
||||
|
||||
|
||||
// privatestuff
|
||||
pl_uChar Type; /* Type of light: PL_LIGHT_* */
|
||||
pl_Float Xp WDL_FIXALIGN;
|
||||
pl_Float Yp, Zp; /* If Type=PL_LIGHT_POINT*,
|
||||
this is Position (PL_LIGHT_POINT_*),
|
||||
otherwise if PL_LIGHT_VECTOR,
|
||||
Unit vector */
|
||||
pl_Float Intensity[3]; /* Intensity. 0.0 is off, 1.0 is full */
|
||||
pl_Float HalfDistSquared; /* Distance squared at which
|
||||
PL_LIGHT_POINT_DISTANCE is 50% */
|
||||
};
|
||||
|
||||
|
||||
class pl_Cam {
|
||||
public:
|
||||
pl_Cam() : m_fBuffer(NULL,0,0,0,false)
|
||||
{
|
||||
m_lastFBScaling=256;
|
||||
m_lastFBWidth=m_lastFBHeight=0;
|
||||
Fov=90.0;
|
||||
AspectRatio=1.0;
|
||||
Sort=1;
|
||||
ClipBack=-1.0;
|
||||
CenterX=CenterY=0;
|
||||
X=Y=Z=0.0;
|
||||
WantZBuffer=false;
|
||||
Pitch=Pan=Roll=0.0;
|
||||
GenMatrix = true;
|
||||
}
|
||||
~pl_Cam()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SetTarget(pl_Float x, pl_Float y, pl_Float z);
|
||||
|
||||
pl_Float Pitch, Pan, Roll; /* Camera angle in degrees in worldspace */
|
||||
pl_Float Fov; /* FOV in degrees valid range is 1-179 */
|
||||
pl_Float AspectRatio; /* Aspect ratio (usually 1.0) */
|
||||
|
||||
pl_Float ClipBack WDL_FIXALIGN; /* Far clipping ( < 0.0 is none) */
|
||||
pl_Float X, Y, Z; /* Camera position in worldspace */
|
||||
|
||||
pl_Float CamMatrix[16]; /* should be rotation-only. translation will mess with the normals */
|
||||
|
||||
pl_sChar Sort; /* Sort polygons, -1 f-t-b, 1 b-t-f, 0 no */
|
||||
pl_sInt CenterX, CenterY; /* Offset center of screen from actual center by this much... */
|
||||
|
||||
pl_Bool WantZBuffer;
|
||||
pl_Bool GenMatrix; /* if set, generates CamMatrix from Pan/Pitch/Roll in Begin() */
|
||||
|
||||
void Begin(LICE_IBitmap *fb, bool want_zbclear=true, pl_ZBuffer zbclear=0.0);
|
||||
void RenderLight(pl_Light *light);
|
||||
void RenderObject(pl_Obj *obj, const pl_Float *bmatrix=NULL, const pl_Float *bnmatrix=NULL);
|
||||
void SortToCurrent(); // sorts all faces added since Begin() or last SortToCurrent() call. useful for if you use zbuffering with transparent objects (draw them last)
|
||||
|
||||
// returns true if onscreen x/y/z are world coordinates
|
||||
bool ProjectCoordinate(pl_Float x, pl_Float y, pl_Float z, pl_Float *screen_x, pl_Float *screen_y, pl_Float *dist); // outputs can be NULL if not needed
|
||||
|
||||
LICE_IBitmap *GetFrameBuffer() { return m_fBuffer.m_buf ? &m_fBuffer : NULL; }
|
||||
WDL_TypedBuf<pl_ZBuffer> zBuffer; /* Z Buffer (validate size before using)*/
|
||||
|
||||
void End();
|
||||
|
||||
int RenderTrisIn;
|
||||
int RenderTrisCulled;
|
||||
int RenderTrisOut;
|
||||
|
||||
double RenderPixelsOut WDL_FIXALIGN;
|
||||
|
||||
void PutFace(pl_Face *TriFace);
|
||||
|
||||
protected:
|
||||
LICE_WrapperBitmap m_fBuffer;
|
||||
pl_uInt m_lastFBWidth, m_lastFBHeight; // unscaled sizes when compared to m_fBuffer
|
||||
pl_uInt m_lastFBScaling;
|
||||
pl_sInt m_lastCX, m_lastCY; // calculated as w/2+CenterX/2 etc
|
||||
|
||||
// internal use
|
||||
void ClipRenderFace(pl_Face *face, pl_Obj *obj);
|
||||
int ClipNeeded(pl_Face *face, pl_Obj *obj); // 0=no draw, 1=drawing (possibly splitting) necessary
|
||||
void RecalcFrustum(int fbw, int fbh);
|
||||
double CalcFOVFactor(double fbw) const
|
||||
{
|
||||
return fbw/tan(plMin(plMax(Fov,1.0),179.0)*(PL_PI/360.0));
|
||||
}
|
||||
|
||||
|
||||
#define PL_NUM_CLIP_PLANES 5
|
||||
|
||||
struct _clipInfo
|
||||
{
|
||||
pl_Vertex newVertices[8];
|
||||
pl_Float ShadeInfos[8][3];
|
||||
pl_Float MappingU[PLUSH_MAX_MAPCOORDS][8];
|
||||
pl_Float MappingV[PLUSH_MAX_MAPCOORDS][8];
|
||||
};
|
||||
|
||||
_clipInfo m_cl[2] WDL_FIXALIGN;
|
||||
pl_Float m_clipPlanes[PL_NUM_CLIP_PLANES][4];
|
||||
pl_Float m_fovfactor, m_adj_asp; // recalculated
|
||||
|
||||
/* Returns: 0 if nothing gets in, 1 or 2 if pout1 & pout2 get in */
|
||||
pl_uInt _ClipToPlane(pl_uInt numVerts, pl_Float *plane);
|
||||
|
||||
|
||||
struct _faceInfo {
|
||||
pl_Float zd;
|
||||
pl_Face *face;
|
||||
pl_Obj *obj;
|
||||
} WDL_FIXALIGN;
|
||||
|
||||
struct _lightInfo {
|
||||
pl_Float l[3];
|
||||
pl_Light *light;
|
||||
} WDL_FIXALIGN;
|
||||
|
||||
static int sortRevFunc(const void *a, const void *b);
|
||||
static int sortFwdFunc(const void *a, const void *b);
|
||||
|
||||
int _numfaces,_numfaces_sorted;
|
||||
WDL_TypedBuf<_faceInfo> _faces;
|
||||
|
||||
int _numlights;
|
||||
WDL_TypedBuf<_lightInfo> _lights;
|
||||
|
||||
void _RenderObj(pl_Obj *, pl_Float *, pl_Float *);
|
||||
|
||||
WDL_HeapBuf _sort_tmpspace;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Object Primitives Code (pl_make.cpp)
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
plMakePlane() makes a plane centered at the origin facing up the y axis.
|
||||
Parameters:
|
||||
w: width of the plane (along the x axis)
|
||||
d: depth of the plane (along the z axis)
|
||||
res: resolution of plane, i.e. subdivisions
|
||||
m: material to use
|
||||
Returns:
|
||||
pointer to object created.
|
||||
*/
|
||||
pl_Obj *plMakePlane(pl_Float w, pl_Float d, pl_uInt res, pl_Mat *m);
|
||||
|
||||
/*
|
||||
plMakeBox() makes a box centered at the origin
|
||||
Parameters:
|
||||
w: width of the box (x axis)
|
||||
d: depth of the box (z axis)
|
||||
h: height of the box (y axis)
|
||||
Returns:
|
||||
pointer to object created.
|
||||
*/
|
||||
pl_Obj *plMakeBox(pl_Float w, pl_Float d, pl_Float h, pl_Mat *m);
|
||||
|
||||
/*
|
||||
plMakeDisc() makes a disc centered at the origin
|
||||
Parameters:
|
||||
r: radius of the disc (x-z axis)
|
||||
divr: division of of disc (around the circle) (>=3)
|
||||
m: material to use
|
||||
Returns:
|
||||
pointer to object created.
|
||||
*/
|
||||
pl_Obj *plMakeDisc(pl_Float r, pl_uInt divr, pl_Mat *m);
|
||||
|
||||
/*
|
||||
plMakeCone() makes a cone centered at the origin
|
||||
Parameters:
|
||||
r: radius of the cone (x-z axis)
|
||||
h: height of the cone (y axis)
|
||||
div: division of cone (>=3)
|
||||
cap: close the big end?
|
||||
m: material to use
|
||||
Returns:
|
||||
pointer to object created.
|
||||
*/
|
||||
pl_Obj *plMakeCone(pl_Float r, pl_Float h, pl_uInt div, pl_Bool cap, pl_Mat *m);
|
||||
|
||||
/*
|
||||
plMakeCylinder() makes a cylinder centered at the origin
|
||||
Parameters:
|
||||
r: radius of the cylinder (x-z axis)
|
||||
h: height of the cylinder (y axis)
|
||||
divr: division of of cylinder (around the circle) (>=3)
|
||||
captop: close the top
|
||||
capbottom: close the bottom
|
||||
m: material to use
|
||||
Returns:
|
||||
pointer to object created.
|
||||
*/
|
||||
pl_Obj *plMakeCylinder(pl_Float r, pl_Float h, pl_uInt divr, pl_Bool captop,
|
||||
pl_Bool capbottom, pl_Mat *m);
|
||||
|
||||
/*
|
||||
plMakeSphere() makes a sphere centered at the origin.
|
||||
Parameters:
|
||||
r: radius of the sphere
|
||||
divr: division of the sphere (around the y axis) (>=3)
|
||||
divh: division of the sphere (around the x,z axis) (>=3)
|
||||
m: material to use
|
||||
Returns:
|
||||
pointer to object created.
|
||||
*/
|
||||
pl_Obj *plMakeSphere(pl_Float r, pl_uInt divr, pl_uInt divh, pl_Mat *m);
|
||||
|
||||
/*
|
||||
plMakeTorus() makes a torus centered at the origin
|
||||
Parameters:
|
||||
r1: inner radius of the torus
|
||||
r2: outer radius of the torus
|
||||
divrot: division of the torus (around the y axis) (>=3)
|
||||
divrad: division of the radius of the torus (x>=3)
|
||||
m: material to use
|
||||
Returns:
|
||||
pointer to object created.
|
||||
*/
|
||||
pl_Obj *plMakeTorus(pl_Float r1, pl_Float r2, pl_uInt divrot,
|
||||
pl_uInt divrad, pl_Mat *m);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** File Readers (pl_read_*.cpp)
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
plRead3DSObj() reads a 3DS object
|
||||
Parameters:
|
||||
fn: filename of object to read
|
||||
m: material to assign it
|
||||
Returns:
|
||||
pointer to object
|
||||
Notes:
|
||||
This reader organizes multiple objects like so:
|
||||
1) the first object is returned
|
||||
2) the second object is the first's first child
|
||||
3) the third object is the second's first child
|
||||
4) etc
|
||||
*/
|
||||
pl_Obj *plRead3DSObj(void *ptr, int size, pl_Mat *m);
|
||||
pl_Obj *plRead3DSObjFromFile(char *fn, pl_Mat *m);
|
||||
pl_Obj *plRead3DSObjFromResource(HINSTANCE hInst, int resid, pl_Mat *m);
|
||||
|
||||
/*
|
||||
plReadCOBObj() reads an ascii .COB object
|
||||
Parameters:
|
||||
fn: filename of object to read
|
||||
mat: material to assign it
|
||||
Returns:
|
||||
pointer to object
|
||||
Notes:
|
||||
This is Caligari's ASCII object format.
|
||||
This reader doesn't handle multiple objects. It just reads the first one.
|
||||
Polygons with lots of sides are not always tesselated correctly. Just
|
||||
use the "Tesselate" button from within truespace to improve the results.
|
||||
*/
|
||||
pl_Obj *plReadCOBObj(char *fn, pl_Mat *mat);
|
||||
|
||||
/*
|
||||
plReadJAWObj() reads a .JAW object.
|
||||
Parameters:
|
||||
fn: filename of object to read
|
||||
m: material to assign it
|
||||
Returns:
|
||||
pointer to object
|
||||
Notes:
|
||||
For information on the .JAW format, please see the jaw3D homepage,
|
||||
http://www.tc.umn.edu/nlhome/g346/kari0022/jaw3d/
|
||||
*/
|
||||
pl_Obj *plReadJAWObj(char *fn, pl_Mat *m);
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Math Code (pl_math.cpp)
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
plMatrixRotate() generates a rotation matrix
|
||||
Parameters:
|
||||
matrix: an array of 16 pl_Floats that is a 4x4 matrix
|
||||
m: the axis to rotate around, 1=X, 2=Y, 3=Z.
|
||||
Deg: the angle in degrees to rotate
|
||||
Returns:
|
||||
nothing
|
||||
*/
|
||||
void plMatrixRotate(pl_Float matrix[], pl_uChar m, pl_Float Deg);
|
||||
|
||||
/*
|
||||
plMatrixTranslate() generates a translation matrix
|
||||
Parameters:
|
||||
m: the matrix (see plMatrixRotate for more info)
|
||||
x,y,z: the translation coordinates
|
||||
Returns:
|
||||
nothing
|
||||
*/
|
||||
void plMatrixTranslate(pl_Float m[], pl_Float x, pl_Float y, pl_Float z);
|
||||
|
||||
/*
|
||||
plMatrixMultiply() multiplies two matrices
|
||||
Parameters:
|
||||
dest: destination matrix will be multipled by src
|
||||
src: source matrix
|
||||
Returns:
|
||||
nothing
|
||||
Notes:
|
||||
this is the same as dest = dest*src (since the order *does* matter);
|
||||
*/
|
||||
void plMatrixMultiply(pl_Float *dest, const pl_Float src[]);
|
||||
|
||||
/*
|
||||
plMatrixApply() applies a matrix.
|
||||
Parameters:
|
||||
m: matrix to apply
|
||||
x,y,z: input coordinate
|
||||
outx,outy,outz: pointers to output coords.
|
||||
Returns:
|
||||
nothing
|
||||
Notes:
|
||||
applies the matrix to the 3d point to produce the transformed 3d point
|
||||
*/
|
||||
void plMatrixApply(pl_Float *m, pl_Float x, pl_Float y, pl_Float z,
|
||||
pl_Float *outx, pl_Float *outy, pl_Float *outz);
|
||||
|
||||
/*
|
||||
plNormalizeVector() makes a vector a unit vector
|
||||
Parameters:
|
||||
x,y,z: pointers to the vector
|
||||
Returns:
|
||||
nothing
|
||||
*/
|
||||
void plNormalizeVector(pl_Float *x, pl_Float *y, pl_Float *z);
|
||||
|
||||
/*
|
||||
plDotProduct() returns the dot product of two vectors
|
||||
Parameters:
|
||||
x1,y1,z1: the first vector
|
||||
x2,y2,z2: the second vector
|
||||
Returns:
|
||||
the dot product of the two vectors
|
||||
*/
|
||||
pl_Float plDotProduct(pl_Float x1, pl_Float y1, pl_Float z1,
|
||||
pl_Float x2, pl_Float y2, pl_Float z2);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* !_PLUSH_H_ */
|
||||
Reference in New Issue
Block a user