YSRESULT YsShellExtEdge_EdgeStaplingUtil::StapleMinimumOpenAngleCorner(YsShellExtEdit &shl) { YsShellVertexHandle cornerVtHd,connVtHd[2]; if(YSOK==GetMinimumOpenAngleCorner(cornerVtHd,connVtHd,shl.Conv())) { // Check again. This crack may have already been fixed. if(YSTRUE!=YsShellExt_TopologyUtil::IsSingleUseEdge(shl.Conv(),cornerVtHd,connVtHd[0]) || YSTRUE!=YsShellExt_TopologyUtil::IsSingleUseEdge(shl.Conv(),cornerVtHd,connVtHd[1])) { return YSERR; } // Either connVtHd[0] must be between connVtHd[1] and cornerVtHd or connVtHd[1] must be between connVtHd[0] and cornerVtHd YSBOOL inBetweenCheck=YSFALSE; for(int i=0; i<2; ++i) { const YsVec3 edVtPos[2]= { shl.GetVertexPosition(connVtHd[1-i]), shl.GetVertexPosition(cornerVtHd) }; const YsVec3 tstPos=shl.GetVertexPosition(connVtHd[i]); if(YSTRUE==YsCheckInBetween3(tstPos,edVtPos)) { inBetweenCheck=YSTRUE; break; } } if(YSTRUE!=inBetweenCheck) { return YSERR; } YsShellExtEdit_TopologyUtil topoUtil; YsShellVertexHandle edVtHd[2],toInsert; if(shl.GetEdgeLength(cornerVtHd,connVtHd[0])<shl.GetEdgeLength(cornerVtHd,connVtHd[1])) { edVtHd[0]=cornerVtHd; edVtHd[1]=connVtHd[1]; toInsert=connVtHd[0]; } else { edVtHd[0]=cornerVtHd; edVtHd[1]=connVtHd[0]; toInsert=connVtHd[1]; } YsShellExtEdit_InsertVertexOnEdge(shl,edVtHd,toInsert); return UpdateCornerAfterStapling(cornerVtHd,shl.Conv()); } return YSERR; }
YSRESULT YsClipLineSeg3 (YsVec3 &newP1,YsVec3 &newP2,const YsVec3 &p1,const YsVec3 &p2,const YsVec3 &range1,const YsVec3 &range2) { int j,nInComp; YsVec3 min,max; YsBoundingBoxMaker3 bbx; bbx.Begin(range1); bbx.Add(range2); bbx.Get(min,max); nInComp=0; for(j=0; j<3; j++) { if(min.GetValue()[j]<=p1.GetValue()[j] && p1.GetValue()[j]<=max.GetValue()[j] && min.GetValue()[j]<=p2.GetValue()[j] && p2.GetValue()[j]<=max.GetValue()[j]) { nInComp++; } if(p1.GetValue()[j]<min.GetValue()[j] && p2.GetValue()[j]<min.GetValue()[j]) { return YSERR; } if(p1.GetValue()[j]>max.GetValue()[j] && p2.GetValue()[j]>max.GetValue()[j]) { return YSERR; } } if(nInComp==3) { newP1=p1; newP2=p2; return YSOK; } YsVec3 c1,c2; if(YsClipInfiniteLine3(c1,c2,p1,p2-p1,min,max)==YSOK) { if(YsCheckInBetween3(c1,p1,p2)==YSTRUE && YsCheckInBetween3(c2,p1,p2)==YSTRUE) { newP1=c1; newP2=c2; return YSOK; } else if(YsCheckInBetween3(c1,p1,p2)==YSTRUE) { // p1-c1 or c1-p2 if(YsCheckInBetween3(p1,c1,c2)==YSTRUE) { newP1=p1; newP2=c1; } else { newP1=c1; newP2=p2; } return YSOK; } else if(YsCheckInBetween3(c2,p1,p2)==YSTRUE) { // p1-c2 or c2-p2 if(YsCheckInBetween3(p1,c1,c2)==YSTRUE) { newP1=p1; newP2=c2; } else { newP1=c2; newP2=p2; } return YSOK; } else { return YSERR; } } else { return YSERR; } }
YSBOOL YsCollisionOfPolygon::CheckCollision(YsVec3 &firstFound) const { int i,j; const YsVec3 *v1,*v2,*u1,*u2; YSSIDE is; YsVec3 crs; if(YsCheckBoundingBoxCollision3(p1min,p1max,p2min,p2max)==YSTRUE) { if(np1>=2 || np2>=3) // Polygon/LineSeg1 vs Plane2 { for(i=0; i<np1; i++) { v1=&p1[i]; v2=&p1[(i+1)%np1]; if(pln2.GetPenetration(crs,*v1,*v2)==YSOK) { is=CheckInsideOfPolygon2(crs); // is=YsCheckInsidePolygon3(crs,np2,p2); if(is==YSINSIDE || is==YSBOUNDARY) { firstFound=crs; return YSTRUE; } } if(pln2.CheckOnPlane(*v1)==YSTRUE) { is=CheckInsideOfPolygon2(*v1); // is=YsCheckInsidePolygon3(*v1,np2,p2); if(is==YSINSIDE || is==YSBOUNDARY) { firstFound=*v1; return YSTRUE; } } } } if(np1>=3 || np2>=2) // Polygon/LineSeg2 vs Plane1 { for(i=0; i<np2; i++) { v1=&p2[i]; v2=&p2[(i+1)%np2]; if(pln1.GetPenetration(crs,*v1,*v2)==YSOK) { is=CheckInsideOfPolygon1(crs); // is=YsCheckInsidePolygon3(crs,np1,p1); if(is==YSINSIDE || is==YSBOUNDARY) { firstFound=crs; return YSTRUE; } } if(pln1.CheckOnPlane(*v1)==YSTRUE) { is=CheckInsideOfPolygon1(*v1); // is=YsCheckInsidePolygon3(*v1,np1,p1); if(is==YSINSIDE || is==YSBOUNDARY) { firstFound=*v1; return YSTRUE; } } } } // If two edges are close to each other... // Threshold is 1% of longer edge. for(i=0; i<np1; i++) { v1=&p1[i]; v2=&p1[(i+1)%np1]; for(j=0; j<np2; j++) { u1=&p2[j]; u2=&p2[(j+1)%np2]; YsVec3 n1,n2; if(YsGetNearestPointOfTwoLine(n1,n2,*v1,*v2,*u1,*u2)==YSOK && YsCheckInBetween3(n1,*v1,*v2)==YSTRUE && YsCheckInBetween3(n2,*u1,*u2)==YSTRUE) { if((n1-n2).GetSquareLength()<YsToleranceSqr) { firstFound=n1; return YSTRUE; } } } } } return YSFALSE; }