diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Winamp/plush/CLIP.C | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Winamp/plush/CLIP.C')
-rw-r--r-- | Src/Winamp/plush/CLIP.C | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/Src/Winamp/plush/CLIP.C b/Src/Winamp/plush/CLIP.C new file mode 100644 index 00000000..5cbd06fe --- /dev/null +++ b/Src/Winamp/plush/CLIP.C @@ -0,0 +1,255 @@ +/****************************************************************************** +Plush Version 1.2 +clip.c +3D Frustum Clipping +Copyright (c) 1996-2000, Justin Frankel +******************************************************************************/ + +#include "plush.h" + +#define NUM_CLIP_PLANES 5 + +typedef struct +{ + pl_Vertex newVertices[8]; + double Shades[8]; + double MappingU[8]; + double MappingV[8]; + double eMappingU[8]; + double eMappingV[8]; +} _clipInfo; + + +static _clipInfo m_cl[2]; + + +static double m_clipPlanes[NUM_CLIP_PLANES][4]; +static pl_Cam *m_cam; +static pl_sInt32 m_cx, m_cy; +static double m_fov; +static double m_adj_asp; + +static void _FindNormal(double x2, double x3, + double y2, double y3, + double zv, + double *res); + + /* Returns: 0 if nothing gets in, 1 or 2 if pout1 & pout2 get in */ +static pl_uInt _ClipToPlane(pl_uInt numVerts, double *plane); + +void plClipSetFrustum(pl_Cam *cam) { + m_adj_asp = 1.0 / cam->AspectRatio; + m_fov = plMin(plMax(cam->Fov,1.0),179.0); + m_fov = (1.0/tan(m_fov*(PL_PI/360.0)))*(double) (cam->ClipRight-cam->ClipLeft); + m_cx = cam->CenterX<<20; + m_cy = cam->CenterY<<20; + m_cam = cam; + memset(m_clipPlanes,0,sizeof(m_clipPlanes)); + + /* Back */ + m_clipPlanes[0][2] = -1.0; + m_clipPlanes[0][3] = -cam->ClipBack; + + /* Left */ + m_clipPlanes[1][3] = 0.00000001; + if (cam->ClipLeft == cam->CenterX) { + m_clipPlanes[1][0] = 1.0; + } + else _FindNormal(-100,-100, + 100, -100, + m_fov*-100.0/(cam->ClipLeft-cam->CenterX), + m_clipPlanes[1]); + if (cam->ClipLeft > cam->CenterX) { + 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 (cam->ClipRight == cam->CenterX) { + m_clipPlanes[2][0] = -1.0; + } + else _FindNormal(100,100, + -100, 100, + m_fov*100.0/(cam->ClipRight-cam->CenterX), + m_clipPlanes[2]); + if (cam->ClipRight < cam->CenterX) { + 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 (cam->ClipTop == cam->CenterY) { + m_clipPlanes[3][1] = -1.0; + } else _FindNormal(100, -100, + 100, 100, + m_fov*m_adj_asp*100.0/(cam->CenterY-cam->ClipTop), + m_clipPlanes[3]); + if (cam->ClipTop > cam->CenterY) { + 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 (cam->ClipBottom == cam->CenterY) { + m_clipPlanes[4][1] = 1.0; + } else _FindNormal(-100, 100, + -100, -100, + m_fov*m_adj_asp*-100.0/(cam->CenterY-cam->ClipBottom), + m_clipPlanes[4]); + if (cam->ClipBottom < cam->CenterY) { + m_clipPlanes[4][0] = -m_clipPlanes[4][0]; + m_clipPlanes[4][1] = -m_clipPlanes[4][1]; + m_clipPlanes[4][2] = -m_clipPlanes[4][2]; + } +} + + +void plClipRenderFace(pl_Face *face) { + pl_uInt k, a, w, numVerts, q; + double tmp, tmp2; + pl_Face newface; + + for (a = 0; a < 3; a ++) { + m_cl[0].newVertices[a] = *(face->Vertices[a]); + m_cl[0].Shades[a] = face->Shades[a]; + m_cl[0].MappingU[a] = face->MappingU[a]; + m_cl[0].MappingV[a] = face->MappingV[a]; + m_cl[0].eMappingU[a] = face->eMappingU[a]; + m_cl[0].eMappingV[a] = face->eMappingV[a]; + } + + numVerts = 3; + q = 0; + a = (m_clipPlanes[0][3] < 0.0 ? 0 : 1); + while (a < NUM_CLIP_PLANES && numVerts > 2) + { + numVerts = _ClipToPlane(numVerts, m_clipPlanes[a]); + memcpy(&m_cl[0],&m_cl[1],sizeof(m_cl)/2); + a++; + } + if (numVerts > 2) { + memcpy(&newface,face,sizeof(pl_Face)); + for (k = 2; k < numVerts; k ++) { + newface.fShade = plMax(0,plMin(face->fShade,1)); + for (a = 0; a < 3; a ++) { + if (a == 0) w = 0; + else w = a+(k-2); + newface.Vertices[a] = m_cl[0].newVertices+w; + newface.Shades[a] = (pl_Float) m_cl[0].Shades[w]; + newface.MappingU[a] = (pl_sInt32)m_cl[0].MappingU[w]; + newface.MappingV[a] = (pl_sInt32)m_cl[0].MappingV[w]; + newface.eMappingU[a] = (pl_sInt32)m_cl[0].eMappingU[w]; + newface.eMappingV[a] = (pl_sInt32)m_cl[0].eMappingV[w]; + newface.Scrz[a] = 1.0f/newface.Vertices[a]->xformedz; + tmp2 = m_fov * newface.Scrz[a]; + tmp = tmp2*newface.Vertices[a]->xformedx; + tmp2 *= newface.Vertices[a]->xformedy; + newface.Scrx[a] = m_cx + ((pl_sInt32)((tmp*(float) (1<<20)))); + newface.Scry[a] = m_cy - ((pl_sInt32)((tmp2*m_adj_asp*(float) (1<<20)))); + } + newface.Material->_PutFace(m_cam,&newface); + plRender_TriStats[3] ++; + } + plRender_TriStats[2] ++; + } +} + +pl_sInt plClipNeeded(pl_Face *face) { + double dr,dl,db,dt; + double f; + dr = (m_cam->ClipRight-m_cam->CenterX); + dl = (m_cam->ClipLeft-m_cam->CenterX); + db = (m_cam->ClipBottom-m_cam->CenterY); + dt = (m_cam->ClipTop-m_cam->CenterY); + f = m_fov*m_adj_asp; + return ((m_cam->ClipBack <= 0.0 || + face->Vertices[0]->xformedz <= m_cam->ClipBack || + face->Vertices[1]->xformedz <= m_cam->ClipBack || + face->Vertices[2]->xformedz <= m_cam->ClipBack) && + (face->Vertices[0]->xformedz >= 0 || + face->Vertices[1]->xformedz >= 0 || + face->Vertices[2]->xformedz >= 0) && + (face->Vertices[0]->xformedx*m_fov<=dr*face->Vertices[0]->xformedz || + face->Vertices[1]->xformedx*m_fov<=dr*face->Vertices[1]->xformedz || + face->Vertices[2]->xformedx*m_fov<=dr*face->Vertices[2]->xformedz) && + (face->Vertices[0]->xformedx*m_fov>=dl*face->Vertices[0]->xformedz || + face->Vertices[1]->xformedx*m_fov>=dl*face->Vertices[1]->xformedz || + face->Vertices[2]->xformedx*m_fov>=dl*face->Vertices[2]->xformedz) && + (face->Vertices[0]->xformedy*f<=db*face->Vertices[0]->xformedz || + face->Vertices[1]->xformedy*f<=db*face->Vertices[1]->xformedz || + face->Vertices[2]->xformedy*f<=db*face->Vertices[2]->xformedz) && + (face->Vertices[0]->xformedy*f>=dt*face->Vertices[0]->xformedz || + face->Vertices[1]->xformedy*f>=dt*face->Vertices[1]->xformedz || + face->Vertices[2]->xformedy*f>=dt*face->Vertices[2]->xformedz)); +} + + + +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; +} + + /* Returns: 0 if nothing gets in, 1 or 2 if pout1 & pout2 get in */ +static pl_uInt _ClipToPlane(pl_uInt numVerts, double *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) { + m_cl[1].Shades[outvert] = m_cl[0].Shades[invert]; + m_cl[1].MappingU[outvert] = m_cl[0].MappingU[invert]; + m_cl[1].MappingV[outvert] = m_cl[0].MappingV[invert]; + m_cl[1].eMappingU[outvert] = m_cl[0].eMappingU[invert]; + m_cl[1].eMappingV[outvert] = m_cl[0].eMappingV[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].Shades[outvert] = m_cl[0].Shades[invert] + + (m_cl[0].Shades[nextvert] - m_cl[0].Shades[invert]) * scale; + m_cl[1].MappingU[outvert] = m_cl[0].MappingU[invert] + + (m_cl[0].MappingU[nextvert] - m_cl[0].MappingU[invert]) * scale; + m_cl[1].MappingV[outvert] = m_cl[0].MappingV[invert] + + (m_cl[0].MappingV[nextvert] - m_cl[0].MappingV[invert]) * scale; + m_cl[1].eMappingU[outvert] = m_cl[0].eMappingU[invert] + + (m_cl[0].eMappingU[nextvert] - m_cl[0].eMappingU[invert]) * scale; + m_cl[1].eMappingV[outvert] = m_cl[0].eMappingV[invert] + + (m_cl[0].eMappingV[nextvert] - m_cl[0].eMappingV[invert]) * scale; + outvert++; + } + curdot = nextdot; + curin = nextin; + invert++; + } + return outvert; +} |