line3d.c

来自「frasr200的win 版本源码(18.21),使用make文件,使用的vc版」· C语言 代码 · 共 2,248 行 · 第 1/5 页

C
2,248
字号
					if((FILLTYPE >= 5) || RAY)
					{  /* calculate illumination normal before persp */

						r0		= r/65536;
						f_cur.x		= xcenter0 + sintheta*sclx*r0;
						f_cur.y		= ycenter0 + costheta*cosphi*scly*r0;
						f_cur.color = -r0*costheta*sinphi;
					}
					if(!(usr_floatflag || RAY))
					{
						if(longpersp(lv,lview,16) == -1)
						{
							cur = bad;
							f_cur = f_bad;
							goto loopbottom;	/* another goto ! */
						}
						cur.x = ((lv[0]+32768L) >> 16) + xxadjust;
						cur.y = ((lv[1]+32768L) >> 16) + yyadjust;
					}
					if(usr_floatflag || overflow || RAY)
					{
						v[0] = lv[0];
						v[1] = lv[1];
						v[2] = lv[2];
						v[0] /= fudge;
						v[1] /= fudge;
						v[2] /= fudge;
						perspective(v);
						cur.x = v[0]+.5 + xxadjust;
						cur.y = v[1]+.5 + yyadjust;
					}
				}
				else if (!(persp && RAY)) /* mrr Not sure how this and 3rd if
													above relate */
				{	/* mrr Why the xx- and yyadjust here and not above? */
					cur.x = f_cur.x = xcenter + sintheta*sclx*r + xxadjust;
					cur.y = f_cur.y = ycenter + costheta*cosphi*scly*r + yyadjust;
					if(FILLTYPE >= 5 || RAY) /* mrr why do we do this for filltype>5? */
						f_cur.color = -r * costheta * sinphi * sclz;
					v[0]=v[1]=v[2]=0;	/* MRR Why do we do this? */
				}
			}
			else /* non-sphere 3D */
			{
				if(!usr_floatflag && !RAY)
				{
					if(FILLTYPE >= 5) /* flag to save vector before perspective */
						lv0[0] = 1;		/* in longvmultpersp calculation */
					else
						lv0[0] = 0;

					/* use 32-bit multiply math to snap this out */
					lv[0] = col;
					lv[0] = lv[0] << 16;
					lv[1] = currow;
					lv[1] = lv[1] << 16;
					if(filetype || pot16bit) /* don't truncate fractional part */
						lv[2] = f_cur.color*65536.0;
					else	/* there IS no fractaional part here! */
					{
						lv[2] = f_cur.color;
						lv[2] = lv[2] << 16;
					}

					if(longvmultpersp(lv,lm,lv0,lv,lview,16) == -1)
					{
						cur	= bad;
						f_cur = f_bad;
						goto loopbottom;
					}

					cur.x = ((lv[0]+32768L) >> 16) + xxadjust;
					cur.y = ((lv[1]+32768L) >> 16) + yyadjust;
					if(FILLTYPE >= 5 && !overflow)
					{
						f_cur.x		= lv0[0];
						f_cur.x			/= 65536.0;
						f_cur.y		= lv0[1];
						f_cur.y			/= 65536.0;
						f_cur.color  = lv0[2];
						f_cur.color /= 65536.0;
					}
				}

				if(usr_floatflag || overflow || RAY)
				/* do in float if integer math overflowed or doing Ray trace */
				{
					/* slow float version for comparison */
					v[0] = col;
					v[1] = currow;
					v[2] = f_cur.color; /* Actually the z value */

					mult_vec(v); /* matrix*vector routine */

					if (FILLTYPE > 4 || RAY)
					{
						f_cur.x	= v[0];
						f_cur.y	= v[1];
						f_cur.color = v[2];

						if(RAY == 6)
						{
							f_cur.x = f_cur.x * (2.0 / xdots) - 1;
							f_cur.y = f_cur.y * (2.0 / ydots) - 1;
							f_cur.color = -f_cur.color * (2.0 / numcolors) - 1;
						}
					}

					if(persp && !RAY)
						perspective(v);
					cur.x = v[0] + xxadjust + .5;
					cur.y = v[1] + yyadjust + .5;

					v[0] = 0;
					v[1] = 0;
					v[2] = WATERLINE;
					mult_vec(v);
					f_water = v[2];
				}
			}

			if (RANDOMIZE)
				if (cur.color > WATERLINE)
				{
					RND = rand15() >> 8;    /* 7-bit number */
					RND = RND * RND >> rand_factor;	/* n-bit number */

					if (rand() & 1)
						RND = -RND; /* Make +/- n-bit number */

					if ((int)(cur.color) + RND >= colors)
						cur.color = colors-2;
					else if ((int)(cur.color) + RND <= WATERLINE)
						cur.color = WATERLINE + 1;
					else
						cur.color = cur.color + RND;
					Real_Color = cur.color;
				}

			if (RAY)
			{
				if (col && currow &&
					old.x > bad_check &&
					old.x < (xdots - bad_check) &&
					lastrow[col].x > bad_check &&
					lastrow[col].y > bad_check &&
					lastrow[col].x < (xdots - bad_check) &&
					lastrow[col].y < (ydots - bad_check))
				{
					/* Get rid of all the triangles in the plane
						at the base of the object */

					if (f_cur.color == f_water &&
						f_lastrow[col].color == f_water &&
						f_lastrow[next].color == f_water)
							goto loopbottom;

					if (RAY != 6) /* Output the vertex info */
						out_triangle(f_cur, f_old, f_lastrow[col],
							cur.color, old.color, lastrow[col].color);

					tout = 1;

					draw_line (old.x, old.y, cur.x, cur.y, old.color);
					draw_line (old.x, old.y, lastrow[col].x,
						lastrow[col].y, old.color);
					draw_line (lastrow[col].x, lastrow[col].y,
						cur.x, cur.y, cur.color);
					num_tris++;
				}

				if (col < lastdot && currow &&
					lastrow[col].x > bad_check &&
					lastrow[col].y > bad_check &&
					lastrow[col].x < (xdots - bad_check) &&
					lastrow[col].y < (ydots - bad_check) &&
					lastrow[next].x > bad_check &&
					lastrow[next].y > bad_check &&
					lastrow[next].x < (xdots - bad_check) &&
					lastrow[next].y < (ydots - bad_check))
				{
					/* Get rid of all the triangles in the plane
					at the base of the object */

					if (f_cur.color == f_water &&
						f_lastrow[col].color == f_water &&
						f_lastrow[next].color == f_water)
							goto loopbottom;

					if (RAY != 6) /* Output the vertex info */
						out_triangle(f_cur, f_lastrow[col], f_lastrow[next],
							cur.color, lastrow[col].color, lastrow[next].color);

					tout = 1;

					draw_line (lastrow[col].x, lastrow[col].y, cur.x, cur.y,
						cur.color);
					draw_line (lastrow[next].x, lastrow[next].y, cur.x, cur.y,
						cur.color);
					draw_line (lastrow[next].x, lastrow[next].y, lastrow[col].x,
						lastrow[col].y, lastrow[col].color);
					num_tris++;
				}

				if (RAY == 6)  /* Output vertex info for Acrospin */
				{
					fprintf (File_Ptr1, "% #4.4f % #4.4f % #4.4f R%dC%d\n",
						f_cur.x, f_cur.y, f_cur.color, RO, CO);
					if (CO > CO_MAX)
						CO_MAX = CO;
					CO++;
				}
				goto loopbottom;

			}

			switch(FILLTYPE)
			{
				case -1:
					if (col &&
					old.x > bad_check &&
					old.x < (xdots - bad_check))
						draw_line (old.x, old.y, cur.x, cur.y, cur.color);
					if (currow &&
					lastrow[col].x > bad_check &&
					lastrow[col].y > bad_check &&
					lastrow[col].x < (xdots - bad_check) &&
					lastrow[col].y < (ydots - bad_check))
						draw_line (lastrow[col].x,lastrow[col].y,cur.x,
							cur.y,cur.color);
					break;
		
				case 0:
					(*plot)(cur.x,cur.y,cur.color);
					break;
		
				case 1:			/* connect-a-dot */
					if ((old.x < xdots) && (col) &&
						old.x > bad_check &&
						old.y > bad_check) /* Don't draw from old to cur on col 0 */
							draw_line(old.x,old.y,cur.x,cur.y,cur.color);
					break;
		
				case 2: /* with interpolation */
				case 3: /* no interpolation */
					/***************************************************************/
					/*  "triangle fill" - consider four points: current point,		*/
					/*  previous point same row, point opposite current point in	*/
					/*  previous row, point after current point in previous row.	*/
					/*  The object is to fill all points inside the two triangles.	*/
					/*																					*/
					/*	lastrow[col].x/y___ lastrow[next]									*/
					/*			  /	1 		/														*/
					/*		    /		1 	  /														*/
					/*			/		1	 / 														*/
					/*  oldrow/col _____ trow/col												*/
					/***************************************************************/
		
					if(currow && !col)
						putatriangle(lastrow[next],lastrow[col],cur,cur.color);
					if(currow && col)		/* skip first row and first column */
					{
						if(col == 1)
							putatriangle(lastrow[col],oldlast,old,old.color);
		
						if(col < lastdot)
							putatriangle(lastrow[next],lastrow[col], cur, cur.color);
						putatriangle(old, lastrow[col], cur, cur.color);
					}
					break;
		
				case 4: /* "solid fill" */
					if (SPHERE)
					{
						if (persp)
						{
							old.x = xcenter>>16;
							old.y = ycenter>>16;
						}
						else
						{
							old.x = xcenter;
							old.y = ycenter;
						}
					}
					else
					{
						lv[0] = col;
						lv[1] = currow;
						lv[2] = 0;
		
						/* apply fudge bit shift for integer math */
						lv[0] = lv[0] << 16;
						lv[1] = lv[1] << 16;
						/* Since 0, unnecessary lv[2] = lv[2] << 16;*/
		
						if(longvmultpersp(lv,lm,lv0,lv,lview,16))
						{
							cur	= bad;
							f_cur = f_bad;
							goto loopbottom;	/* another goto ! */
						}
		
						/*	Round and fudge back to original  */
						old.x = (lv[0]+32768L) >> 16;
						old.y = (lv[1]+32768L) >> 16;
					}
					if (old.x < 0)
						old.x = 0;
					if (old.x >= xdots)
						old.x = xdots-1;
					if (old.y < 0)
						old.y = 0;
					if (old.y >= ydots)
						old.y = ydots-1;
					draw_line(old.x,old.y,cur.x,cur.y,cur.color);
					break;
		
				case 5:
				case 6:
					/* light-source modulated fill */
					if(currow && col)		/* skip first row and first column */
					{
						if(f_cur.color < bad_check || f_old.color < bad_check ||
							f_lastrow[col].color < bad_check)
								break;
		
						v1[0] = f_cur.x		- f_old.x;
						v1[1] = f_cur.y		- f_old.y;
						v1[2] = f_cur.color - f_old.color;
		
						v2[0] = f_lastrow[col].x			- f_cur.x;
						v2[1] = f_lastrow[col].y			- f_cur.y;
						v2[2] = f_lastrow[col].color - f_cur.color;
		
						cross_product (v1, v2, cross);
		
						/* normalize cross - and check if non-zero */
						if(normalize_vector(cross))
						{
							if(debugflag)
							{
								static char far msg[] = {"debug, cur.color=bad"};
								stopmsg(0,msg);
							}
							cur.color = f_cur.color = bad.color;
						}
						else
						{
							/* line-wise averaging scheme */
							if(LIGHTAVG>0)
							{
								if(crossnotinit)
								{
									/* initialize array of old normal vectors */
									crossavg[0] = cross[0];
									crossavg[1] = cross[1];
									crossavg[2] = cross[2];
									crossnotinit = 0;
								}
								tmpcross[0] = (crossavg[0]*LIGHTAVG+cross[0]) /
								   (LIGHTAVG+1);
								tmpcross[1] = (crossavg[1]*LIGHTAVG+cross[1]) /
								   (LIGHTAVG+1);
								tmpcross[2] = (crossavg[2]*LIGHTAVG+cross[2]) /
								   (LIGHTAVG+1);
			
								cross[0] = tmpcross[0];
								cross[1] = tmpcross[1];
								cross[2] = tmpcross[2];

								if(normalize_vector(cross))
								{
									/* this shouldn't happen */
									if(debugflag)
									{
										static char far msg[] =
										{"debug, normal vector err2"};
										stopmsg(0,msg);
										/* use next instead if you ever need details:
										static char far tmp[] = {"debug, vector err"};
										char msg[200];
#ifndef XFRACT
										sprintf(msg,"%Fs\n%f %f %f\n%f %f %f\n%f %f %f",
#else
										sprintf(msg,"%s\n%f %f %f\n%f %f %f\n%f %f %f",
#endif
										tmp, f_cur.x, f_cur.y, f_cur.color,
										f_lastrow[col].x, f_lastrow[col].y,
										f_lastrow[col].color, f_lastrow[col-1].x,
										f_lastrow[col-1].y,f_lastrow[col-1].color);
										stopmsg(0,msg);
										*/
									}
									cur.color = f_cur.color = colors;
								}
							}
							crossavg[0] = tmpcross[0];
							crossavg[1] = tmpcross[1];
							crossavg[2] = tmpcross[2];

							/* dot product of unit vectors is cos of angle between */
							/* we will use this value to shade surface */
		
							cur.color = 1 + (colors-2) *
								(1.0-dot_product(cross,light_direction));
						}
						/* if colors out of range, set them to min or max color 
							index but avoid background index. This makes colors
							"opaque" so SOMETHING plots. These conditions shouldn't 
							happen but just in case					*/
						if(cur.color < 1)			/* prevent transparent colors */
							cur.color = 1;		/* avoid background */
						if(cur.color > colors-1)
							cur.color = colors-1;
		
					/* why "col < 2"? So we have sufficient geometry for the fill */
					/* algorithm, which needs previous point in same row to have  */
					/* already been calculated (variable old)		*/
					/* fix ragged left margin in preview */
						if (col == 1 && currow > 1)
							putatriangle(lastrow[next],lastrow[col],cur,cur.color);
		
						if(col < 2 || currow < 2) /* don't have valid colors yet */
							break;
		
						if(col < lastdot)
							putatriangle(lastrow[next],lastrow[col],cur,cur.color);
						putatriangle(old,lastrow[col],cur,cur.color);
		
						plot=standardplot;
					}
					break;
			}  /*	End of CASE statement for fill type  */
		
loopbottom:

			if (RAY || (FILLTYPE != 0 && FILLTYPE != 4))
			{
				/* for triangle and grid fill purposes */
				oldlast = lastrow[col];
				old = lastrow[col] = cur;
		
				/* for illumination model purposes */
				f_old	= f_lastrow[col] = f_cur;
				if (currow && RAY && col >= lastdot)
				/* if we're at the end of a row, close the object */
				{
					end_object(tout);
					tout=0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?