home *** CD-ROM | disk | FTP | other *** search
Java Source | 1996-08-14 | 12.0 KB | 394 lines |
- /*----------------------------------------------------------------------*/
- /* Solid -- represents a convex solid object with polygonal faces
- - holds an orientation matrix(orient), screen coords (cenx,ceny),
- width and height (W,H), polygons, points, normal vectors
- to faces, shading colours.
- - methods:
- getSolidData - reads in the solids information (in a very
- specific way
- setColours - sets up the shading colours
- getColour - decides the shading of a particular face
- CalcScrPts - calculates the screen points from the 3D points
- faceUp - decides whether to draw the face or not
- Draw - draws the solid
- DropFace - prints only the top face (flat with no tilt)
- DrawPoly - draws a particular polygon of the solid
- DropBlank - draws blank faces...this is equivalent to
- DropFace except no pattern is drawn
- ExplodePrep - prepares for Explode
- Explode - a little demo of the before a DropFace the non-
- essential face fly away
- StampPrep - prepares for Stamp
- Stamp - a little demo of the before a DropFace the solid
- rotates around
- */
- /*----------------------------------------------------------------------*/
- /* Jim Morey -- morey@math.ubc.ca -- January 24, 1996 */
- /*----------------------------------------------------------------------*/
-
- import java.io.*;
- import java.awt.*;
- import java.lang.*;
- import java.awt.Color;
- import java.net.*;
- import Omatrix;
-
- public class Solid extends Object{
- private final double FLOOR=-1.05;
-
- public Omatrix orient;
- public int cenx,ceny,W,H;
- public double Scale;
- public int[][] polygons;
-
- private Omatrix demoMid,demoInitial;
- private double demoAngle;
- private int demoFace;
- private double[][] points,explode;
- private double[][] rotPts;
- private int[][] scrPts;
- private int[][] faces;
- private Color colours[][];
- private int npoint,npoly,nface,ncolour;
- private int p,i,j,k,min,f,face,colour;
- private double lightvec[],Zeye;
- private int x[],y[];
-
- Solid(InputStream is, int wid, int heig, int ncolour_)
- throws IOException{
- getSolidData(is);
- rotPts = new double[npoint][3];
- scrPts = new int[npoint][2];
-
- /* .. regular setup .. */
-
- double len = Math.sqrt(lightvec[0]*lightvec[0] +
- lightvec[1]*lightvec[1] + lightvec[2]*lightvec[2]);
- lightvec[0] = lightvec[0]/len;
- lightvec[1] = lightvec[1]/len;
- lightvec[2] = lightvec[2]/len;
-
- x = new int[20];
- y = new int[20];
- W = wid / 2;
- H = heig / 2;
- ncolour = ncolour_;
- colours = new Color[ncolour][2];
- setColours();
-
- orient = new Omatrix();
- demoInitial = new Omatrix();
- demoMid = new Omatrix();
-
- double max=0;
- for (i=0;i<npoint;i++){
- len = Math.sqrt(points[i][0]*points[i][0] +
- points[i][1]*points[i][1] + points[i][2]*points[i][2]);
- if (len >max) max = len;
- }
-
- if (W>H) Scale= (double)H/max/1.2;
- else Scale= (double)W/max/1.2;
-
- for (i=0;i<nface;i++){
- len = Math.sqrt(points[i][0]*points[i][0] +
- points[i][1]*points[i][1] + points[i][2]*points[i][2]);
- points[i][0] = points[i][0]/len;
- points[i][1] = points[i][1]/len;
- points[i][2] = points[i][2]/len;
- }
-
- CalcScrPts((double)W,(double)H,0);
- }
-
- /* - - - - - - - - - - - - - - - */
- void getSolidData(InputStream is) throws IOException{
- String str, name, thing;
- int count;
-
- StreamTokenizer token = new StreamTokenizer(is);
- token.eolIsSignificant(false);
- token.commentChar('#');
-
- token.nextToken();
- Zeye = token.nval;
- /* .. get the points .. */
- token.nextToken();
- npoint = (int)token.nval;
- points = new double[npoint][3];
- for (i=0;i<npoint;i++){
- for (j=0;j<3;j++){
- token.nextToken();
- points[i][j] = token.nval;
- }
- }
-
- /* .. get the polygons .. */
- token.nextToken();
- npoly = (int)token.nval;
- polygons = new int[npoly][];
- for (i=0;i<npoly;i++){
- token.nextToken();
- count = (int)token.nval;
- polygons[i] = new int[count+2];
- polygons[i][0] = count;
- for (j=1;j<count+2;j++){
- token.nextToken();
- polygons[i][j] = (int)token.nval;
- }
- }
-
- /* .. get the faces .. */
- token.nextToken();
- nface = (int)token.nval;
- faces = new int[nface][];
- explode = new double[nface][5];
- for (i=0;i<nface;i++){
- token.nextToken();
- count = (int)token.nval;
- faces[i] = new int[count+1];
- faces[i][0] = count;
- for (j=1;j<count+1;j++){
- token.nextToken();
- faces[i][j] = (int)token.nval;
- }
- }
-
- lightvec = new double[3];
- for (j=0;j<3;j++){
- token.nextToken();
- lightvec[j] = token.nval;
- }
- }
-
- /* - - - - - - - - - - - - - - - */
- public void setColours(){
- for (i=0;i<ncolour;i++){
- colours[i][0]= new Color(255 -(ncolour-1-i)*100/ncolour,
- 255 -(ncolour-1-i)*100/ncolour,255 -(ncolour-1-i)*100/ncolour);
- colours[i][1]= new Color(255 -(ncolour-1-i)*100/ncolour,0,0);
- }
- }
-
- /* - - - - - - - - - - - - - - - */
- public Color getColour(int f,int index){
- int colour = (int)((rotPts[f][0]*lightvec[0]+
- rotPts[f][1]*lightvec[1] +
- rotPts[f][2]*lightvec[2])*ncolour);
-
- if (colour<0) colour = 0;
- if (colour>ncolour-1) colour = ncolour-1;
-
- return colours[colour][polygons[faces[f][index]][1]];
- }
-
- /* - - - - - - - - - - - - - - - */
- public void CalcScrPts(double x,double y,double z){
- double persp;
-
- for (p=0;p<npoint;p++){
- rotPts[p][2] = points[p][0]*orient.M[2][0] +
- points[p][1]*orient.M[2][1] +
- points[p][2]*orient.M[2][2];
- rotPts[p][0] = points[p][0]*orient.M[0][0] +
- points[p][1]*orient.M[0][1] +
- points[p][2]*orient.M[0][2];
- rotPts[p][1] = -points[p][0]*orient.M[1][0] -
- points[p][1]*orient.M[1][1] -
- points[p][2]*orient.M[1][2];
- }
- for (p=nface;p<npoint;p++){
- rotPts[p][2] += z;
- persp = (Zeye - rotPts[p][2])/(Scale*Zeye);
- if (persp != 0);
- scrPts[p][0] = (int)(rotPts[p][0]/persp+x);
- scrPts[p][1] = (int)(rotPts[p][1]/persp+y);
- }
- }
-
- /* - - - - - - - - - - - - - - - */
- public boolean faceUp(int f){
- return (rotPts[f][0]*rotPts[nface+f][0] +
- rotPts[f][1]*rotPts[nface+f][1] +
- rotPts[f][2]*(rotPts[nface+f][2]-Zeye) < 0);
- }
-
- /* - - - - - - - - - - - - - - - */
- public void Draw(Graphics offscreen,int x0,int y0,double z){
- CalcScrPts((double)x0,(double)y0,z);
- /* .. for non-convex solids (not used)..
- i=0;
- for (f=0;f<nface;f++)
- if (faceUp(f)) {
- topface[i] = f;
- i++;
- }
- for (j=0;j<i-1;j++){
- min = j;
- for (k=j+1;k<i;k++)
- if (rotPts[topface[k]][2]<rotPts[topface[min]][2]) min =k;
- if (min !=j) {
- f = topface[j];
- topface[j] = topface[min];
- topface[min] = f;
- }
- }
- */
-
- for (f=0;f<nface;f++){
- if (faceUp(f))
- for (j=1;j<faces[f][0]+1;j++)
- DrawPoly(offscreen,faces[f][j],getColour(f,j));
- }
- }
-
- /* - - - - - - - - - - - - - - - */
- public void StampPrep(Omatrix tilt){
- Omatrix tmp = new Omatrix();
- demoInitial.Equal(orient);
- CalcScrPts(0,0,0);
- demoFace=0;
- for (j=1;j<nface;j++){
- if (rotPts[j][2]>rotPts[demoFace][2]) demoFace = j;
- }
- }
-
- /* - - - - - - - - - - - - - - - */
- public void Stamp(Graphics offscreen,int x0,int y0,double t){
- Omatrix tmp = new Omatrix();
- tmp.Rotation(0,2,Math.PI*t);
- orient=tmp.Times(demoInitial);
- Draw(offscreen,(int)(x0+30*Math.sin(Math.PI*t)), y0,
- FLOOR*t+(1-t)*2*Math.sin(Math.PI*t));
- }
-
- /* - - - - - - - - - - - - - - - */
- public void ExplodePrep(Omatrix tilt){
- /* .. random parameters for faces .. */
- for (j=0;j<nface;j++){
- for (i=0;i<4;i++)
- explode[j][i] = Math.random()*2 - 1;
- explode[j][4] = Math.random();
- }
-
- demoInitial.Equal(orient);
- orient = tilt.Transpose().Times(orient);
- CalcScrPts(0,0,0);
- demoFace=0;
- for (j=1;j<nface;j++)
- if (rotPts[j][2]>rotPts[demoFace][2]) demoFace = j;
-
- demoAngle = demoMid.FindTran(demoInitial,orient);
- }
-
- /* - - - - - - - - - - - - - - - */
- public void Explode(Graphics offscreen,int x0,int y0,double t){
- /* .. there will be some problems with depth! .. */
- Omatrix tmp = new Omatrix();
- Omatrix tmp2 = new Omatrix();
-
- for (j=0;j<nface;j++){
- if (j == demoFace){
- tmp.Rotation(1,2,demoAngle*t);
- orient=demoMid.Times(tmp.Times(demoMid.Transpose().Times(demoInitial)));
- CalcScrPts((double)x0,(double)y0,
- FLOOR*t+(1-t)*Math.sin(Math.PI*t));
- } else {
- tmp.Rotation(1,2,10*explode[j][0]*t);
- tmp2.Rotation(0,2,10*explode[j][1]*t);
- orient = tmp.Times(tmp2.Times(demoInitial));
- CalcScrPts((double)x0+t*200*explode[j][2],
- (double)y0+t*200*explode[j][3],
- 0+t*explode[j][4]);
- }
- for (i=1;i<faces[j][0]+1;i++)
- DrawPoly(offscreen,faces[j][i],getColour(j,i));
- }
- }
-
- /* - - - - - - - - - - - - - - - */
- public void DropFace(Graphics offscreen,Omatrix tilt, int x0,int y0,boolean level){
- orient = tilt.Transpose().Times(orient);
- int max=0;
- if (level){
- CalcScrPts((double)x0,(double)y0,FLOOR-1);
- for (j=1;j<nface;j++) if (rotPts[j][2]>rotPts[max][2]) max = j;
- } else {
- Omatrix tmp = new Omatrix();
- tmp.Rotation(0,2,Math.PI);
- orient = tmp.Times(orient);
- CalcScrPts((double)x0,(double)y0,1+FLOOR);
- for (j=1;j<nface;j++) if (rotPts[j][2]<rotPts[max][2]) max = j;
- orient = tmp.Times(orient);
- }
-
- for (j=1;j<faces[max][0]+1;j++)
- DrawPoly(offscreen,faces[max][j],colours[ncolour-1][polygons[faces[max][j]][1]]);
-
- orient = tilt.Times(orient);
- }
-
- /* - - - - - - - - - - - - - - - */
- private void DrawPoly(Graphics offscreen,int poly,Color colour){
- for (p=2;p<polygons[poly][0]+2;p++){
- x[p-2] = scrPts[polygons[poly][p]][0];
- y[p-2] = scrPts[polygons[poly][p]][1];
- }
- offscreen.setColor(colour);
- offscreen.fillPolygon(x,y,polygons[poly][0]);
- offscreen.setColor(Color.black);
- offscreen.drawPolygon(x,y,polygons[poly][0]);
- }
-
- /* - - - - - - - - - - - - - - - */
- public void DropBlank(Graphics offscreen,int poly,Omatrix tilt,int x0,int y0,boolean level){
- orient = tilt.Transpose().Times(orient);
- if (level){
- CalcScrPts((double)x0,(double)y0,FLOOR-1);
- } else {
- Omatrix tmp = new Omatrix();
- tmp.Rotation(0,2,Math.PI);
- orient = tmp.Times(orient);
- CalcScrPts((double)x0,(double)y0,(1+FLOOR));
- orient = tmp.Times(orient);
- }
-
- DrawPoly(offscreen,poly,Color.lightGray);
-
- orient = tilt.Times(orient);
- }
-
- /* - - - - - - - - - - - - - - - */
- public String toString() {
- String str;
-
- str ="Zeye "+Zeye+"\npoints "+npoint+"\n ";
- for (i=0;i<npoint;i++){
- str = str.concat(" "+i+
- " ("+points[i][0]+" "+points[i][1]+" "+points[i][2]+")\n");
- }
-
- str = str.concat("polys "+npoly+" \n");
- for (i=0;i<npoly;i++){
- str = str.concat(" "+i+">>(");
- for (j=1;j<polygons[i][0]+2;j++){
- str = str.concat(" "+polygons[i][j]);
- }
- str = str.concat(")\n");
- }
-
- str = str.concat("faces "+nface+" \n");
- for (i=0;i<nface;i++){
- str = str.concat(" "+i+">>(");
- for (j=1;j<faces[i][0]+1;j++){
- str = str.concat(" "+faces[i][j]);
- }
- str = str.concat(")\n");
- }
-
- str = str.concat("light ("+lightvec[0]+" "+lightvec[1]+" "+lightvec[2]+")");
-
- return str;
- }
- }
-