84static void clip_tri_to_slab(
114static void clear_scan_table(
void);
116static void fixup_scan_table(
120static void scan_edge(
169 for ( i = 0; i < object_list.
Num_Nodes(); i++ )
172 INode * inode = object_list[i];
173 Object * obj = inode->EvalWorldState(time).obj;
174 TriObject * tri = (TriObject *)obj->ConvertToType(time, triObjectClassID);
175 Mesh * mesh = &(tri->mesh);
176 Matrix3 objtm = inode->GetObjectTM(time);
182 unsigned faces = mesh->getNumFaces();
183 for (
unsigned face_index = 0; face_index < faces; ++ face_index )
185 Face & face = mesh->faces [ face_index ];
188 Point3 a = mesh->verts [ face.v[0] ] * delta;
189 Point3 b = mesh->verts [ face.v[1] ] * delta;
190 Point3 c = mesh->verts [ face.v[2] ] * delta;
236 double start_x, start_y, end_x, end_y;
240 if ( a.z < z && b.z < z && c.z < z )
243 if ( a.z > z && b.z > z && c.z > z )
248 if ( a.z < z && b.z >= z )
250 start_x = a.x + (b.x - a.x) * (z - a.z) / (b.z - a.z);
251 start_y = a.y + (b.y - a.y) * (z - a.z) / (b.z - a.z);
253 else if ( b.z < z && c.z >= z )
255 start_x = b.x + (c.x - b.x) * (z - b.z) / (c.z - b.z);
256 start_y = b.y + (c.y - b.y) * (z - b.z) / (c.z - b.z);
258 else if ( c.z < z && a.z >= z )
260 start_x = c.x + (a.x - c.x) * (z - c.z) / (a.z - c.z);
261 start_y = c.y + (a.y - c.y) * (z - c.z) / (a.z - c.z);
270 if ( a.z >= z && b.z < z )
272 end_x = a.x + (b.x - a.x) * (z - a.z) / (b.z - a.z);
273 end_y = a.y + (b.y - a.y) * (z - a.z) / (b.z - a.z);
275 else if ( b.z >= z && c.z < z )
277 end_x = b.x + (c.x - b.x) * (z - b.z) / (c.z - b.z);
278 end_y = b.y + (c.y - b.y) * (z - b.z) / (c.z - b.z);
280 else if ( c.z >= z && a.z < z )
282 end_x = c.x + (a.x - c.x) * (z - c.z) / (a.z - c.z);
283 end_y = c.y + (a.y - c.y) * (z - c.z) / (a.z - c.z);
291 Draw_Line(start_x, start_y, end_x, end_y);
320 double delta_x = fabs (x1 - x0);
321 double delta_y = fabs (y1 - y0);
323 if ( delta_x > delta_y )
337 double step_y = (y1 - y0) / delta_x;
339 double y = y0 + step_y * (floor (x0 + 1) - x0);
341 for (
int x = (
int) x0; x < (int) x1; ++ x )
366 double step_x = (x1 - x0) / delta_y;
368 double x = x0 + step_x * (floor (y0 + 1) - y0);
370 for (
int y = (
int) y0; y < (int) y1; ++ y )
372 if ( (
int) x >= 0 && (
int) x < 256 )
413 if (numverts == 0)
return;
418 float miny = polyvert[0].
Pos.y;
419 float maxy = polyvert[0].
Pos.y;
421 for (i=1; i<numverts; i++) {
422 if (polyvert[i].Pos.y < miny) miny = polyvert[i].
Pos.y;
423 if (polyvert[i].Pos.y > maxy) maxy = polyvert[i].
Pos.y;
427 int start = numverts - 1;
428 for (i=0; i<numverts; i++) {
429 scan_edge(polyvert[start],polyvert[i]);
434 fixup_scan_table((
int)floor(miny),(
int)floor(maxy));
437 for (i=(
int)floor(miny); i<=(int)floor(maxy); i++) {
442 _scantab[i].P[
LEFT].Pos.x,
443 _scantab[i].P[
LEFT].Pos.y,
444 _scantab[i].P[
RIGHT].Pos.x,
445 _scantab[i].P[
RIGHT].Pos.y);
463static void clip_tri_to_slab
476 memset(outverts,0,
sizeof(outverts));
477 memset(tmpverts,0,
sizeof(tmpverts));
480 outverts[0].
Pos = p0;
481 outverts[1].
Pos = p1;
482 outverts[2].
Pos = p2;
483 outverts[0].
Bary = Point3(1.0f,0.0f,0.0f);
484 outverts[1].
Bary = Point3(0.0f,1.0f,0.0f);
485 outverts[2].
Bary = Point3(0.0f,0.0f,1.0f);
491 clip_poly(tmpverts,*setnum,outverts,setnum,
PlaneClass(
Vector3(0.0f,0.0f,-1.0f),z1));
523 p0 = inverts[innum-1];
524 for (i=0; i<innum; i++) {
527 if (inside(p1,clipplane)) {
528 if (inside(p0,clipplane)) {
529 output(p1,outverts,outnum);
531 pi = intersect(p0,p1,clipplane);
532 output(pi,outverts,outnum);
533 output(p1,outverts,outnum);
536 if (inside(p0,clipplane)) {
537 pi = intersect(p0,p1,clipplane);
538 output(pi,outverts,outnum);
565 poly[*numverts] = outvert;
588 float dist = p.
Pos.x * plane.
N[0] + p.
Pos.y * plane.
N[1] + p.
Pos.z * plane.
N[2] + plane.
D;
618 Point3 delta = p1.
Pos - p0.
Pos;
620 float num = -( plane.
N[0] * p0.
Pos.x +
621 plane.
N[1] * p0.
Pos.y +
622 plane.
N[2] * p0.
Pos.z + plane.
D );
624 float den = plane.
N[0] * delta.x +
625 plane.
N[1] * delta.y +
626 plane.
N[2] * delta.z;
636 i.Bary = (1.0f - t) * p0.
Bary + t*p1.
Bary;
653static void clear_scan_table(
void)
655 memset(_scantab,0,
sizeof(_scantab));
656 for (
int i=0; i<256; i++) {
674static void fixup_scan_table(
int y0,
int y1)
680 for (i=y0; i<=y1; i++) {
681 if (_scantab[i].P[
LEFT].Pos.x > _scantab[i].P[
RIGHT].Pos.x) {
683 _scantab[i].P[
LEFT] = _scantab[i].P[
RIGHT];
684 _scantab[i].P[
RIGHT] = tmp;
689 for (i=y0; i<y1; i++) {
690 if (_scantab[i+1].P[
RIGHT].Pos.x < _scantab[i].P[
LEFT].Pos.x) {
692 _scantab[i+1].P[
RIGHT].Pos.x = _scantab[i].P[
LEFT].Pos.x;
694 }
else if (_scantab[i+1].P[
LEFT].Pos.x > _scantab[i].P[
RIGHT].Pos.x) {
696 _scantab[i+1].P[
LEFT].Pos.x = _scantab[i].P[
RIGHT].Pos.x;
722 if (floor(p0.
Pos.y) == floor(p1.
Pos.y)) {
724 int si = (int)floor(p0.
Pos.y);
727 if (p0.
Pos.x < p1.
Pos.x) {
739 if (left->
Pos.x < _scantab[si].P[
LEFT].Pos.x) {
740 _scantab[si].P[
LEFT] = *left;
743 if (right->
Pos.x > _scantab[si].P[
RIGHT].Pos.x) {
744 _scantab[si].P[
RIGHT] = *right;
750 _scantab[si].P[
LEFT] = *left;
751 _scantab[si].P[
RIGHT] = *right;
761 if (p0.
Pos.y < p1.
Pos.y) {
772 for (
double y = floor(top->
Pos.y); y <= floor(bot->
Pos.y); y += 1.0f) {
775 double t = (y - floor(top->
Pos.y)) / (floor(bot->
Pos.y) - floor(top->
Pos.y));
778 _scantab[(int)y].P[side].Pos = (1.0f - (
float)t)*top->
Pos + (float)t*bot->
Pos;
781 _scantab[(int)y].P[side].Bary = (1.0f - (
float)t)*top->
Bary + (float)t*bot->
Bary;
Color scale(const Color &a, const Color &b)
unsigned Num_Nodes(void) const
void Intersect_Triangle(Point3 a, Point3 b, Point3 c, float z)
void Add_Solid(int x, int y)
void Scan_Triangle(Point3 a, Point3 b, Point3 c)
sint8 Solid[max_bitmap_width][max_bitmap_height]
void Draw_Line(double x0, double y0, double x1, double y1)
WWINLINE Quaternion Inverse(const Quaternion &a)