void FsLazyWindowApplication::CacheBoundingBox(void) { auto nVtx=vtx.size()/3; // Cache bounding box if(0<nVtx) { float minx,miny,minz,maxx,maxy,maxz; minx=vtx[0]; miny=vtx[1]; minz=vtx[2]; maxx=vtx[0]; maxy=vtx[1]; maxz=vtx[2]; for(decltype(nVtx) i=0; i<nVtx; ++i) { YsMakeSmaller(minx,vtx[i*3]); YsMakeSmaller(miny,vtx[i*3+1]); YsMakeSmaller(minz,vtx[i*3+2]); YsMakeGreater(maxx,vtx[i*3]); YsMakeGreater(maxy,vtx[i*3+1]); YsMakeGreater(maxz,vtx[i*3+2]); } min.Set(minx,miny,minz); max.Set(maxx,maxy,maxz); } else { min=YsVec3::Origin(); max=YsVec3::Origin(); } }
void YsClassSample::Motion(int x,int y) { double dx,dy; YsVec3 vec; dx=double(x-lastX); dy=double(lastY-y); switch(mouseMode) { case 0: eyeAtt.NoseUp(dy/300.0); eyeAtt.YawLeft(-dx/300.0); break; case 1: vec.Set(-dx/30.0,-dy/30.0,0.0); vec=eyeAtt.GetMatrix()*vec; eyeLookAt=eyeLookAt+vec; break; case 2: RotatePolygon(dy/300.0,-dx/300.0); break; case 3: vec.Set(dx/30.0,dy/30.0,0.0); vec=eyeAtt.GetMatrix()*vec; pointOfInterest=pointOfInterest+vec; break; } lastX=x; lastY=y; }
void Motion(int x,int y) { if(button==GLUT_DOWN) { double dx,dy; YsVec3 vec; dx=double(x-lastX); dy=double(lastY-y); switch(mouseMode) { case 0: eyeAtt.NoseUp(dy/300.0); eyeAtt.YawLeft(-dx/300.0); break; case 1: vec.Set(-dx/30.0,-dy/30.0,0.0); vec=eyeAtt.GetMatrix()*vec; eyeLookAt=eyeLookAt+vec; break; } glutPostRedisplay(); } lastX=x; lastY=y; }
void Display(void) { double matBuf[4*4]; YsVec3 eyePos; YsMatrix4x4 eyeTfm; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); eyePos.Set(0.0,0.0,eyeDistance); eyePos=eyeAtt.GetMatrix()*eyePos; eyeTfm.Initialize(); eyeTfm.Translate(eyePos); eyeTfm.Rotate(eyeAtt); eyeTfm.Invert(); eyeTfm.Translate(-eyeLookAt); eyeTfm.GetArray(matBuf); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMultMatrixd(matBuf); DrawShell(sh1,blu,drawInPolygon); DrawShell(sh2,grn,drawInPolygon); DrawAxis(5.0); glFlush(); glutSwapBuffers(); }
void YsClassSample::Display(void) { BIPOSATT biEyePos; BIPOINT cursor; eyePos.Set(0.0,0.0,-eyeDistance); eyePos=eyeAtt.GetMatrix()*eyePos; eyePos=eyeLookAt+eyePos; BiSetPoint(&biEyePos.p,eyePos.x(),eyePos.y(),eyePos.z()); BiSetAngleDeg(&biEyePos.a, YsRadToDeg(eyeAtt.h()), YsRadToDeg(eyeAtt.p()), YsRadToDeg(eyeAtt.b())); BiClearScreen(); BiStartBuffer(&biEyePos); BiSetPoint(&cursor, pointOfInterest.x(), pointOfInterest.y(), pointOfInterest.z()); BiInsMarker(&cursor,&BiWhite,BIMK_CROSS); DrawSlashedPolygon(); DrawPolygon(4,q,blu,YSFALSE); DrawPolygon(4,r,blu,YSFALSE); DrawAxis(5.0); BiFlushBuffer(); BiSwapBuffers(); }
void Display(void) { double matBuf[4*4]; YsVec3 eyePos; YsMatrix4x4 eyeTfm; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); eyePos.Set(0.0,0.0,eyeDistance); eyePos=eyeAtt.GetMatrix()*eyePos; eyeTfm.Initialize(); eyeTfm.Translate(eyePos); eyeTfm.Rotate(eyeAtt); eyeTfm.Invert(); eyeTfm.Translate(-eyeLookAt); eyeTfm.GetArray(matBuf); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMultMatrixd(matBuf); DrawSeparatablePair(nVtx,vtx); glFlush(); glutSwapBuffers(); }
YSRESULT YsZClip(YsVec3 &clipPos,const YsVec3 &p1,const YsVec3 &p2,const double &clipz) { const double denom=(p2.z()-p1.z()); if(YsTolerance<=fabs(denom)) { const YsVec3 v=p2-p1; const double t=(clipz-p1.z())/denom; clipPos.Set(p1[0]+t*v[0],p1[1]+t*v[1],clipz); return YSOK; } return YSERR; }
void YsClassSample::MainLoop(void) { int lb,mb,rb; long mx,my; eyeDistance=10.0; eyeLookAt.Set(0.0,0.0,0.0); eyeAtt.Set(0.0,0.0,0.0); pointOfInterest.Set(0.0,0.0,-1.0); PrepareSquare(p); PrepareSquare(q); RotatePolygon(q,YsDegToRad(90.0),0.0); PrepareSquare(r); RotatePolygon(r,0.0,YsDegToRad(90.0)); BiMouse(&lb,&mb,&rb,&mx,&my); mouseMode=0; while((key=BiInkey())!=BIKEY_ESC) { BIPROJ prj; BiUpdateDevice(); BiGetStdProjection(&prj); BiSetProjection(&prj); Key(key); Display(); lastX=mx; lastY=my; BiMouse(&lb,&mb,&rb,&mx,&my); if(lb==BI_ON && (mx!=lastX || my!=lastY)) { Motion(mx,my); } } }
void YsTransform3DCoordToScreenCoord(YsVec3 &scrn,const YsVec3 &from,const int viewport[4],const YsMatrix4x4 &projViewModelTfm) { double pos4d[4]={from.x(),from.y(),from.z(),1.0}; projViewModelTfm.Mul(pos4d,pos4d); pos4d[0]/=pos4d[3]; pos4d[1]/=pos4d[3]; pos4d[2]/=pos4d[3]; pos4d[0]=(double)viewport[0]+(double)viewport[2]*(pos4d[0]+1.0)/2.0; pos4d[1]=(double)viewport[1]+(double)viewport[3]*(pos4d[1]+1.0)/2.0; scrn.Set(pos4d[0],pos4d[1],pos4d[2]); }
void YsTransformScreenCoordTo3DCoord(YsVec3 &threeD,const YsVec3 &scrn,const int viewport[4],const YsMatrix4x4 &projViewModelTfm) { double pos4d[4]= { (scrn.x()-(double)viewport[0])*2.0/(double)viewport[2]-1.0, (scrn.y()-(double)viewport[1])*2.0/(double)viewport[3]-1.0, scrn.z(), 1.0 }; projViewModelTfm.MulInverse(pos4d,pos4d); pos4d[0]/=pos4d[3]; pos4d[1]/=pos4d[3]; pos4d[2]/=pos4d[3]; threeD.Set(pos4d[0],pos4d[1],pos4d[2]); }
void Display(void) { double matBuf[4*4]; YsVec3 eyePos; YsMatrix4x4 eyeTfm; YsVec3 p; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); eyePos.Set(0.0,0.0,eyeDistance); eyePos=eyeAtt.GetMatrix()*eyePos; eyeTfm.Initialize(); eyeTfm.Translate(eyePos); eyeTfm.Rotate(eyeAtt); eyeTfm.Invert(); eyeTfm.Translate(-eyeLookAt); eyeTfm.GetArray(matBuf); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMultMatrixd(matBuf); DrawAxis(5.0); glDisable(GL_LIGHTING); glColor3d(1.0,1.0,1.0); glBegin(GL_LINES); glVertex3d(0.0,0.0,0.0); glVertex3d(axisOfOrbit.x()*5.0,axisOfOrbit.y()*5.0,axisOfOrbit.z()*5.0); glEnd(); rot.RotatePositive(p,orbiter); glPushMatrix(); glTranslatef(p.x()*5.0,p.y()*5.0,p.z()*5.0); DrawCursor(); glPopMatrix(); glFlush(); glutSwapBuffers(); }
static YSRESULT YsClip3DLine (YsVec3 &clip,const YsVec3 &org,const YsVec3 &vec,const double &clipPoint,int component) { int c1,c2; double buf[3],slope[3]; if(component==0) { c1=1; c2=2; } else if(component==1) { c1=0; c2=2; } else { c1=0; c2=1; } if(YsAbs(vec.GetValue()[component])>=YsTolerance) { slope[c1]=vec.GetValue()[c1]/vec.GetValue()[component]; slope[c2]=vec.GetValue()[c2]/vec.GetValue()[component]; buf[component]=clipPoint; buf[c1]=org.GetValue()[c1]+slope[c1]*(clipPoint-org.GetValue()[component]); buf[c2]=org.GetValue()[c2]+slope[c2]*(clipPoint-org.GetValue()[component]); clip.Set(buf[0],buf[1],buf[2]); return YSOK; } else { return YSERR; } }
static YSRESULT YsClipInfiniteLine3_FindSecondIntersection (YsVec3 &itsc,const YsVec3 &first,const YsVec3 &vec,const YsVec3 range[2]) { int i,j,k; double dist,d; YSRESULT found; YsVec3 candidate; found=YSERR; dist=-1.0; candidate.Set(0.0,0.0,0.0); for(i=0; i<3; i++) { for(j=0; j<2; j++) { if(YsClip3DLine(candidate,first,vec,range[j].GetValue()[i],i)==YSOK) { for(k=0; k<3; k++) { if(i!=k && (candidate.GetValue()[k]<range[0].GetValue()[k]-YsTolerance || range[1].GetValue()[k]+YsTolerance<candidate.GetValue()[k])) { goto NEXTPLANE; } } found=YSOK; d=(first-candidate).GetSquareLength(); if(d>dist) { itsc=candidate; dist=d; } } NEXTPLANE: ; } } return found; }
int main(int argc, char** argv) { InitYsClass(); axisOfOrbit.Set(1.0,1.0,1.0); axisOfOrbit.Normalize(); orbiter=axisOfOrbit.GetArbitraryParpendicularVector(); orbiter.Normalize(); rot.Set(axisOfOrbit,0.0); printf("Keys\n"); printf("A....Viewing Rotation Mode\n"); printf("B....Viewing Translation (Scroll) Mode\n"); printf("Z....Zoom\n"); printf("M....Mooz\n"); printf("----------\n"); eyeAtt.Set(YsPi/2.0,0.0,0.0); eyeDistance=10.0; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); InitOpenGL(); glutDisplayFunc(Display); glutReshapeFunc(Reshape); glutKeyboardFunc(Keyboard); glutMouseFunc(Mouse); glutMotionFunc(Motion); glutIdleFunc(Idle); glutMainLoop(); return 0; }
YSRESULT YsShell::LoadTri(const char fn[]) { FILE *fp; int nNod,nTri; YsShellVertexHandle *nodVtHd; int ac; char buf[256],str[256],*av[32]; nNod=0; nTri=0; nodVtHd=NULL; fp=fopen(fn,"r"); if(fp!=NULL) { while(fgets(str,256,fp)!=NULL) { strcpy(buf,str); YsArguments(&ac,av,32,buf); if(ac>0) { if(strcmp(av[0],"nofnod")==0) { int i; nNod=atoi(av[1]); nodVtHd=new YsShellVertexHandle [nNod+1]; if(nodVtHd==NULL) { YsExceptionHandler::Exception(YsExceptionHandler::OUTOFMEMORY,"YsShell::LoadTri()"); } for(i=0; i<nNod; i++) { nodVtHd[i]=NULL; } } else if(strcmp(av[0],"noftri")==0) { nTri=atoi(av[1]); } else if(strcmp(av[0],"nod")==0) { if(nodVtHd!=NULL) { int ndId; YsVec3 pos; ndId=atoi(av[1]); pos.Set(atof(av[2]),atof(av[3]),atof(av[4])); nodVtHd[ndId]=AddVertexH(pos); } else { YsErrOut("YsShell::LoadTri()\n"); YsErrOut(" nofnod didn't come before nod\n"); fclose(fp); goto ERREND; } } else if(strcmp(av[0],"tri")==0) { YsShellVertexHandle vtHd[3]; vtHd[0]=nodVtHd[atoi(av[2])]; vtHd[1]=nodVtHd[atoi(av[3])]; vtHd[2]=nodVtHd[atoi(av[4])]; if(vtHd[0]!=NULL && vtHd[1]!=NULL && vtHd[2]!=NULL) { AddPolygonH(3,vtHd); } else { YsErrOut("YsShell::LoadTri()\n"); YsErrOut(" Nodes must be defined before triangles.\n"); fclose(fp); goto ERREND; } } } } } fclose(fp); return YSOK; ERREND: if(nodVtHd!=NULL) { delete [] nodVtHd; } return YSERR; }
YSRESULT YsShell::MergeMs3(const char fn[]) { FILE *fp; YsArray <YsShellVertexHandle> vtHdList; fp=fopen(fn,"r"); if(fp!=NULL) { char buf[256]; YsShellVertexHandle plVtHd[4]; while(fgets(buf,255,fp)!=NULL) { if('#'==buf[0]) { continue; } int ac; char *av[16]; if(YsArguments(&ac,av,16,buf)==YSOK && ac>0) { if(av[0][0]=='v' || av[0][0]=='V') { if(ac>=4) { YsShellVertexHandle vtHd; YsVec3 pos; double x,y,z; x=atof(av[1]); y=atof(av[2]); z=atof(av[3]); pos.Set(x,y,z); vtHd=AddVertexH(pos); vtHdList.Append(vtHd); } else { goto ERREND; } } else if(av[0][0]=='D' || av[0][0]=='d') // D:Delta=Triangle { if(ac>=4) { plVtHd[0]=vtHdList[atoi(av[1])]; plVtHd[1]=vtHdList[atoi(av[2])]; plVtHd[2]=vtHdList[atoi(av[3])]; SetColorOfPolygon(AddPolygonH(3,plVtHd),YsBlue()); } else { goto ERREND; } } else if(av[0][0]=='Q' || av[0][0]=='q') { if(ac>=5) { plVtHd[0]=vtHdList[atoi(av[1])]; plVtHd[1]=vtHdList[atoi(av[2])]; plVtHd[2]=vtHdList[atoi(av[3])]; plVtHd[3]=vtHdList[atoi(av[4])]; SetColorOfPolygon(AddPolygonH(4,plVtHd),YsBlue()); } else { goto ERREND; } } } } fclose(fp); return YSOK; } ERREND: if(fp!=NULL) { fclose(fp); } return YSERR; }
YSRESULT YsShell::MergeDat(const char fn[]) { FILE *fp; YsArray <YsShellVertexHandle> vtHdList; fp=fopen(fn,"r"); if(fp!=NULL) { char buf[4096]; YsArray <YsShellVertexHandle,64> plVtHd; while(fgets(buf,4095,fp)!=NULL) { int ac; char *av[1024]; if(YsArguments(&ac,av,1024,buf)==YSOK && ac>0) { if(av[0][0]=='v' || av[0][0]=='V') { if(ac>=4) { YsShellVertexHandle vtHd; YsVec3 pos; double x,y,z; x=atof(av[1]); y=atof(av[2]); z=atof(av[3]); pos.Set(x,y,z); vtHd=AddVertexH(pos); vtHdList.Append(vtHd); } else { goto ERREND; } } else if(av[0][0]=='f' || av[0][0]=='F') // D:Delta=Triangle { if(ac>=4) { int i; YsShellPolygonHandle plHd; plVtHd.Set(ac-1,NULL); for(i=0; i<ac-1; i++) { plVtHd[i]=vtHdList[atoi(av[i+1])]; } plHd=AddPolygonH(ac-1,vtHdList); SetColorOfPolygon(plHd,YsBlue()); } else { goto ERREND; } } } } fclose(fp); return YSOK; } ERREND: if(fp!=NULL) { fclose(fp); } return YSERR; }
YSBOOL YsCollisionOfPolygon::CheckIntersectionBetweenPolygon1AndBlock(const YsVec3 &corner1,const YsVec3 &corner2) const { int i; YsVec3 is,cube[8]; // YsVec3 face[4]; // int cubeFaceIdx[6][4]= // { // {0,1,2,3}, // {4,5,6,7}, // {0,1,5,4}, // {1,2,6,5}, // {2,3,7,6}, // {3,0,4,7} // }; static const int cubeEdgeIdx[12][2]= { {0,1},{1,2},{2,3},{3,0}, {4,5},{5,6},{6,7},{7,4}, {0,4},{1,5},{2,6},{3,7} }; int np; const YsVec3 *p; YsBoundingBoxMaker3 bbx; YsVec3 min,max; np=GetNumVertexOfPolygon1(); p=GetVertexListOfPolygon1(); // Constrain min and max bbx.Begin(corner1); bbx.Add(corner2); bbx.Get(min,max); if(YsCheckBoundingBoxCollision3(p1min,p1max,min,max)!=YSTRUE) { return YSFALSE; } cube[0].Set(min.x(),min.y(),min.z()); cube[1].Set(max.x(),min.y(),min.z()); cube[2].Set(max.x(),max.y(),min.z()); cube[3].Set(min.x(),max.y(),min.z()); cube[4].Set(min.x(),min.y(),max.z()); cube[5].Set(max.x(),min.y(),max.z()); cube[6].Set(max.x(),max.y(),max.z()); cube[7].Set(min.x(),max.y(),max.z()); // If all corners are one side of the plane, no intersection int nSide[3]; nSide[0]=0; nSide[1]=0; nSide[2]=0; for(i=0; i<8; i++) { // Old Implementation (modified 10/24/2001) // nSide[pln1.GetSideOfPlane(cube[i])+1]++; // Modified 10/24/2001; int side; side=pln1.GetSideOfPlane(cube[i]); nSide[side+1]++; if(side==0) { YSSIDE sideOfPolygon; sideOfPolygon=CheckInsideOfPolygon1(cube[i]); // sideOfPolygon=YsCheckInsidePolygon3(cube[i],np1,p1); if(sideOfPolygon==YSINSIDE || sideOfPolygon==YSBOUNDARY) { return YSTRUE; } } } if((nSide[0]==0 && nSide[1]==0 && nSide[2]>0) || (nSide[0]>0 && nSide[1]==0 && nSide[2]==0)) { return YSFALSE; } // One of the point is contained inside the region for(i=0; i<np; i++) { if(YsCheckInsideBoundingBox3(p[i],min,max)==YSTRUE) { return YSTRUE; } } // One of the edges of the block intersect with the polygon for(i=0; i<12; i++) { if(CheckIntersectionBetweenPolygon1AndLineSegment(cube[cubeEdgeIdx[i][0]],cube[cubeEdgeIdx[i][1]])==YSTRUE) { return YSTRUE; } } // One of the face of the box intersect with the polygon (kind of corner cutting) const int xComp=0,yComp=1,zComp=2; static const int componentTable[3][3]= { {xComp,yComp,zComp}, // Left,Right face : Normal in xComp direction, region in yComp,zComp plane {yComp,xComp,zComp}, // Top,Bottom face : Normal in yComp direction, region in xComp,zComp plane {zComp,xComp,yComp} // Front,Back face : Normal in zComp direction, region in xComp,yComp plane }; static const double dirTable[3][3]= { {1.0,0.0,0.0}, // Normal for Left/Right face {0.0,1.0,0.0}, // Normal for Top/Bottom face {0.0,0.0,1.0} // Normal for Front/Back face }; for(i=0; i<3; i++) { int j,k; YsVec2 plnRegion1,plnRegion2; int nomComp,plnComp1,plnComp2; YsVec3 nom; nomComp=componentTable[i][0]; plnComp1=componentTable[i][1]; plnComp2=componentTable[i][2]; plnRegion1.Set(min.GetValue()[plnComp1]-YsTolerance,min.GetValue()[plnComp2]-YsTolerance); plnRegion2.Set(max.GetValue()[plnComp1]+YsTolerance,max.GetValue()[plnComp2]+YsTolerance); nom.Set(dirTable[nomComp][0],dirTable[nomComp][1],dirTable[nomComp][2]); for(j=0; j<2; j++) { YsPlane pln; YsVec3 org; org=(j==0 ? min : max); pln.Set(org,nom); for(k=0; k<np1; k++) { YsVec3 x1,x2; YsVec2 ref; x1=p1[k]; x2=p1[(k+1)%np1]; if(pln.GetPenetration(is,x1,x2)==YSOK) { ref.Set(is.GetValue()[plnComp1],is.GetValue()[plnComp2]); if(YsCheckInsideBoundingBox2(ref,plnRegion1,plnRegion2)==YSTRUE) { return YSTRUE; } } } } } return YSFALSE; }
YSBOOL YsBoundingBoxMaker3::IsInside(const YsVec2 &pos) const { YsVec3 ref; ref.Set(pos.x(),pos.y(),0.0); return YsCheckInsideBoundingBox3(ref,min,max); }
YSRESULT YsShell::MergeMsh(const char fn[]) { FILE *fp; int nNod,nEl2; YsShellVertexHandle *nodVtHd; int ac; char buf[256],str[256],*av[32]; nNod=0; nEl2=0; nodVtHd=NULL; fp=fopen(fn,"r"); if(fp!=NULL) { while(fgets(str,256,fp)!=NULL) { int i; for(i=0; str[i]!=0; i++) { if(str[i]=='#') { str[i]=0; break; } } strcpy(buf,str); YsArguments(&ac,av,32,buf); if(ac>0) { if(strcmp(av[0],"nofnod")==0) { int i; nNod=atoi(av[1]); nodVtHd=new YsShellVertexHandle [nNod+1]; if(nodVtHd==NULL) { YsExceptionHandler::Exception(YsExceptionHandler::OUTOFMEMORY,"YsShell::MergeMsh()"); } for(i=0; i<nNod; i++) { nodVtHd[i]=NULL; } } else if(strcmp(av[0],"nofel2")==0) { nEl2=atoi(av[1]); } else if(strcmp(av[0],"nod")==0) { if(nodVtHd!=NULL) { int ndId; YsVec3 pos; ndId=atoi(av[1]); pos.Set(atof(av[2]),atof(av[3]),atof(av[4])); nodVtHd[ndId]=AddVertexH(pos); } else { YsErrOut("YsShell::LoadTri()\n"); YsErrOut(" nofnod didn't come before nod\n"); fclose(fp); goto ERREND; } } else if(strcmp(av[0],"el2")==0) { YsShellVertexHandle vtHd[4]; if(atoi(av[2])==3) { vtHd[0]=nodVtHd[atoi(av[3])]; vtHd[1]=nodVtHd[atoi(av[4])]; vtHd[2]=nodVtHd[atoi(av[5])]; if(vtHd[0]!=NULL && vtHd[1]!=NULL && vtHd[2]!=NULL) { AddPolygonH(3,vtHd); } } else if(atoi(av[2])==4) { vtHd[0]=nodVtHd[atoi(av[3])]; vtHd[1]=nodVtHd[atoi(av[4])]; vtHd[2]=nodVtHd[atoi(av[5])]; vtHd[3]=nodVtHd[atoi(av[6])]; if(vtHd[0]!=NULL && vtHd[1]!=NULL && vtHd[2]!=NULL && vtHd[3]!=NULL) { AddPolygonH(4,vtHd); } } else { YsErrOut("YsShell::LoadMsh()\n"); YsErrOut(" Load Error\n"); YsErrOut(" Refered to undefined node or non-tri&non-quad element\n"); fclose(fp); goto ERREND; } } } } } fclose(fp); return YSOK; ERREND: if(nodVtHd!=NULL) { delete [] nodVtHd; } return YSERR; }