makesphere.c 5.05 KB
/*====================================================================
 * makesphere.c
 *
 * Copyright 1995, Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
 * Inc.; the contents of this file may not be disclosed to third
 * parties, copied or duplicated in any form, in whole or in part,
 * without the prior written permission of Silicon Graphics, Inc.
 *
 * RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to
 * restrictions as set forth in subdivision (c)(1)(ii) of the Rights
 * in Technical Data and Computer Software clause at DFARS
 * 252.227-7013, and/or in similar or successor clauses in the FAR,
 * DOD or NASA FAR Supplement. Unpublished - rights reserved under the
 * Copyright Laws of the United States.
 *====================================================================*/


/* to make type:
cc -o makesphere makesphere.c -lm
makesphere -t > sphere.dl
makesphere > sphere.dat
*/

#include <stdio.h>
#include <math.h>

#define PI		3.14159
#define PLUSCLAMP(x)	((x>127)?127:x)
#define MINUSCLAMP(x)	((x<-128)?-128:x)
#define NCL(x)		PLUSCLAMP(MINUSCLAMP((int)x))

float sscale=32.0, tscale=32.0;
float minx=-100, maxx=100;
float miny=-100, maxy=100;
float minz=-100, maxz=100;
float mins=0.0,maxs=1.0,steps=10.0;
float mint=0.0,maxt=1.0,stept=10.0;
int   func=0, dodata=1;
char  name[64];

void sphere(float s, float t, float *x, float *y, float *z, float *nx, float *ny, float *nz);

void (*functions[])(float s, float t, float *x, float *y, float *z, float *nx, float *ny, float *nz) = {
	sphere,
};

void dosphere()
{
	float s,t,x,y,z,nx,ny,nz;
	float stps, stpt;
	int   block=0,is,it;
	
	
	stps=(maxs-mins)/steps;
	stpt=(maxt-mint)/stept;
	for (s=mins; s<maxs; s += stps) {
	for (t=mint; t<maxt; t += stpt) {
	  if (dodata) {
		printf("static Vtx %s_vtx_%d[4] = {\n",name,block++);
		(*functions[func])(s,t,&x,&y,&z,&nx,&ny,&nz);
                is = ((s)*sscale); is = (is >= sscale) ? sscale-1 : is;
                it = ((t)*tscale); it = (it >= tscale) ? tscale-1 : it;
		printf("{%4d,%4d,%4d, 0, ( %i<<6), ( %i<<6), %4d, %4d, %4d, 0xff },\n",
			(int) x, (int) y, (int) z, 
                        is, it,
			NCL( nx), NCL( ny), NCL( nz));
		(*functions[func])(s,t+stpt,&x,&y,&z,&nx,&ny,&nz);
                is = ((s)*sscale); is = (is >= sscale) ? sscale-1 : is;
                it = ((t+stpt)*tscale); it = (it >= tscale) ? tscale-1 : it;
		printf("{%4d,%4d,%4d, 0, ( %i<<6), (%i<<6), %4d, %4d, %4d, 0xff },\n",
			(int) x, (int) y, (int) z, 
                        is, it,
			NCL( nx), NCL( ny), NCL( nz));
		(*functions[func])(s+stps,t+stpt,&x,&y,&z,&nx,&ny,&nz);
                is = ((s+stps)*sscale); is = (is >= sscale) ? sscale-1 : is;
                it = ((t+stpt)*tscale); it = (it >= tscale) ? tscale-1 : it;
		printf("{%4d,%4d,%4d, 0, (%i<<6), (%i<<6), %4d, %4d, %4d, 0xff },\n",
			(int) x, (int) y, (int) z, 
                        is, it,
			NCL( nx), NCL( ny), NCL( nz));
		(*functions[func])(s+stps,t,&x,&y,&z,&nx,&ny,&nz);
                is = ((s+stps)*sscale); is = (is >= sscale) ? sscale-1 : is;
                it = ((t)*tscale); it = (it >= tscale) ? tscale-1 : it;
		printf("{%4d,%4d,%4d, 0, (%i<<6), (%i<<6), %4d, %4d, %4d, 0xff },\n",
			(int) x, (int) y, (int) z, 
                        is, it,
			NCL( nx), NCL( ny), NCL( nz));
		printf("};\n");
	  } else {
		printf("    gsSPVertex(&%s_vtx_%d, 4, 0),\n",name,block++);
		printf("    gsSP1Triangle(0,2,1,0),\n");
		printf("    gsSP1Triangle(0,3,2,0),\n");
	  }
	}
	}

}


void sphere(float s, float t, float *x, float *y, float *z, float *nx, float *ny, float *nz)
{
	float r;
	

	*y = sin((t-0.5)*PI) * (maxy-miny)/2.0 + (maxy+miny)/2.0;
	r = cos((t-0.5)*PI);
	*x = r * sin(s*2*PI) * (maxx-minx)/2.0 + (maxx+minx)/2.0;
	*z = r * cos(s*2*PI) * (maxz-minz)/2.0 + (maxz+minz)/2.0;

	*nx = *x - (maxx+minx)/2;
	*ny = *y - (maxy+miny)/2;
	*nz = *z - (maxz+minz)/2;


	r = *nx * *nx + *ny * *ny + *nz * *nz;
	if (r<10) {
		fprintf(stderr,"ERROR sum of normals %f < 10\n",r);
		exit(1);
	}
	r = 1/sqrt(r);
	*nx *= r*128;
	*ny *= r*128;
	*nz *= r*128;

}

void useage() 
{
	printf("makesphere: tesselate a surface and print data\n");
	printf("  makesphere <options>      (data sent to standard output)\n");
	printf("OPTIONS:\n");
	printf("h - print this message\n");
	printf("r - sphere resolution\n");
	printf("S - s scale argument\n");
	printf("T - t scale argument\n");
	printf("t - print out triangle commands to be inserted in display list\n");
	printf("d - print out data (static variable declarations) (default)\n");
	exit(1);
}

void doargs(int argc, char *argv[])
{
	int i=1;
	while (i<argc) {
	    switch((argv[i][0]=='-')?argv[i][1]:argv[i][0]) {
		case 'd': dodata=1; break;
		case 't': dodata=0; break;
		case 'S': sscale=atof(argv[i+1]); i++; break;
		case 'T': tscale=atof(argv[i+1]); i++; break;
		case 'r': steps=stept=atof(argv[i+1]); i++; break;
		case 'h':
		default:
			useage();
	    }
	    i++;
	}
 
        sprintf(name,"sphere%i",(int)steps);
}

void main(int argc, char *argv[])
{
	doargs(argc,argv);
	dosphere();
	exit(0);
}