int APITestUtil::MakeTestUVLoftSurface(NURBSSet &nset) { Matrix3 scale = ScaleMatrix(Point3(50, 50, 50)); Matrix3 rotate = RotateZMatrix(PI/2.0f); int cu0 = P1Curve(nset, scale * TransMatrix(Point3(0, 0, 0))); int cu1 = P1Curve(nset, scale * TransMatrix(Point3(0, 0, 20))); int cu2 = P1Curve(nset, scale * TransMatrix(Point3(0, 0, 40))); int cv0 = P2Curve(nset, TransMatrix(Point3(50, 50, 0))); int cv1 = P2Curve(nset, TransMatrix(Point3(-50, 50, 0))); int cv2 = P2Curve(nset, TransMatrix(Point3(-50, -50, 0))); int cv3 = P2Curve(nset, TransMatrix(Point3(50, -50, 0))); NURBSUVLoftSurface *s = new NURBSUVLoftSurface(); s->SetName(GetString(IDS_UVLOFT_SURFACE)); s->SetNSet(&nset); s->AppendUCurve(cu0); s->AppendUCurve(cu1); s->AppendUCurve(cu2); s->AppendVCurve(cv0); s->AppendVCurve(cv1); s->AppendVCurve(cv2); s->AppendVCurve(cv3); return nset.AppendObject(s); }
// 2D에서 어떤 점과 원의 접선의 접점 구하기 void MGetContactPoint(rvector ContactPoint[2], rvector& Point, rvector& CircleCenter, float fCircleRadius) { rvector ToCircle = CircleCenter - Point; float fLengthToCircle = (float)sqrt(ToCircle.x*ToCircle.x + ToCircle.y*ToCircle.y); float fAngle = (float)asin(min(max(fCircleRadius/fLengthToCircle, -1.0f), 1.0f)); rvector LineEnd; float t; rvector ToContact1 = TransformVector(ToCircle, RotateZMatrix(fAngle)); LineEnd = Point + ToContact1; MGetPointFromPointToLine(&(ContactPoint[0]), &t, CircleCenter, Point, LineEnd); // Left rvector ToContact2 = TransformVector(ToCircle, RotateZMatrix(-fAngle)); LineEnd = Point + ToContact2; MGetPointFromPointToLine(&(ContactPoint[1]), &t, CircleCenter, Point, LineEnd); // Right }
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int nCmdShow) { { // code block Helper::Window mainWindow( hInstance, nCmdShow, &WndProc, L"Skinning", L"skinning", 4 ); D3DPRESENT_PARAMETERS params; ZeroMemory( ¶ms, sizeof( params ) ); params.Windowed = TRUE; params.SwapEffect = D3DSWAPEFFECT_DISCARD; params.BackBufferFormat = D3DFMT_UNKNOWN; params.EnableAutoDepthStencil = TRUE; params.AutoDepthStencilFormat = D3DFMT_D16; params.MultiSampleType = D3DMULTISAMPLE_NONE; D3D::GraphicDevice graphicDevice( mainWindow.GetHWND(), params ); graphicDevice.SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME ); graphicDevice.SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); Helper::SpectatorCoords spectatorCoords( 40.0f, D3DX_PI / 2, -D3DX_PI / 2 ); Cylinder cylinder(nPointsPerCircle, nPointsPerGeneratrix, Height, Radius, graphicDevice, Freq, MaxAngle); cylinder.SetPositionMatrix( RotateZMatrix(D3DX_PI/2)*TranslationMatrix(0, -Height/2*0, 0) ); cylinder.SetViewMatrix( ViewMatrix( spectatorCoords.GetCartesianCoords(), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 1.0f, 0.0f)) ); cylinder.SetProjectiveMatrix( ProjectiveMatrix( FrontClippingPlane, BackClippingPlane ) ); SetWindowLong(mainWindow.GetHWND(), 0, reinterpret_cast<LONG>(&spectatorCoords)); SetWindowLong(mainWindow.GetHWND(), sizeof(LONG), reinterpret_cast<LONG>(&cylinder)); MSG msg; ZeroMemory(&msg, sizeof(msg)); while( msg.message != WM_QUIT ) { if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { Render(graphicDevice, spectatorCoords, cylinder); } } } // code block _CrtDumpMemoryLeaks(); return 0; }
void APITestUtil::PointTests() { // now let's build a test object NURBSSet nset; Matrix3 mat; mat.IdentityMatrix(); // 6 types of points... // 1: build an independent point int indPnt = MakeTestPoint(nset); // 2: now a constrained point int ptPnt = MakeTestPointCPoint(nset, indPnt); // build a cv curve int cvCrv = MakeTestCVCurve(nset, mat); // 3: a constrained point on that curve int crvPnt = MakeTestCurveCPoint(nset, cvCrv); // build a cv surface int cvSurf = MakeTestCVSurface(nset, mat); // 4: a constrained point on that surface int srfPnt = MakeTestSurfCPoint(nset, cvSurf); // 5: Curve Curve intersection point int cvCrv1 = MakeTestCVCurve(nset, TransMatrix(Point3(65, 0, 0)) * RotateZMatrix(0.5)); int intPoint = MakeTestCurveCurve(nset, cvCrv, cvCrv1, FALSE); // 6: Curve Surface intersection point. int cvCrv2 = MakeTestCVCurve(nset, RotateXMatrix(PI/2.0f) * TransMatrix(Point3(0, 0, -175))); int srfIntPoint = MakeTestCurveSurface(nset, cvSurf, cvCrv2); Object *obj = CreateNURBSObject(mpIp, &nset, mat); INode *node = mpIp->CreateObjectNode(obj); node->SetName(GetString(IDS_PNT_TEST_OBJECT)); mpIp->RedrawViews(mpIp->GetTime()); }
bool RotateViewMouseProc::OnMouseMove(HWND hwnd, int point, int flag, const IPoint2& screenPt ) { DbgAssert(mStarted); if ( ! mViewport || ! mViewport->IsAlive() ) { DbgAssert(!_T("Viewport is not valid!")); return false; } SetCursor(mCursor); IPoint2 mCurScreenPt = screenPt; if (abs(screenPt.y - mOldScreenPt.y) > abs(screenPt.x - mOldScreenPt.x)) // Constrain in X mCurScreenPt.x = mOldScreenPt.x; else // Constrain in Y mCurScreenPt.y = mOldScreenPt.y; // find out the user is moving the mouse in which direction IPoint2 delta = mCurScreenPt - mOldScreenPt; Point3 center; Matrix3 svmat; mViewport->GetAffineTM(svmat); if(mViewport->GetViewType() == VIEW_PERSP_USER) center = Point3(0.0f, 0.0f, -mViewport->GetFocalDist()) - svmat.GetTrans(); else center = svmat.GetTrans();//mViewport->getOffset(); float angle = (flag & MOUSE_CTRL) ? 10.0f : 1.0f; if (delta.x < 0) // Going left { if (flag & MOUSE_SHIFT) mViewport->Rotate( RotateZMatrix( DegToRad(angle) ), center ); else mViewport->Rotate( Inverse(svmat) * RotateZMatrix( DegToRad(angle) ) * svmat, center ); } else if (delta.x > 0) // Going Right { if (flag & MOUSE_SHIFT) mViewport->Rotate( RotateZMatrix( -DegToRad(angle) ), center ); else mViewport->Rotate( Inverse(svmat) * RotateZMatrix( -DegToRad(angle) ) * svmat, center ); } else if (delta.y < 0) // going Up { mViewport->Rotate( RotateXMatrix( DegToRad(angle) ), center ); } else // Going down { mViewport->Rotate( RotateXMatrix( -DegToRad(angle) ), center ); } mViewport->Invalidate(); Interface10* ip = GetCOREInterface10(); ip->RedrawViews(ip->GetTime(), REDRAW_INTERACTIVE); mOldScreenPt = screenPt; return mStarted; }
void TorusObject::BuildMesh(TimeValue t) { Point3 p; int ix,na,nb,nc,nd,jx,kx; int nf=0,nv=0; float delta,ang; float delta2,ang2; int sides,segs,smooth; float radius,radius2, rotation; float sinang,cosang, sinang2,cosang2,rt; float twist, pie1, pie2, totalPie, startAng = 0.0f; int doPie = TRUE; int genUVs = TRUE; // Start the validity interval at forever and widdle it down. ivalid = FOREVER; pblock->GetValue(PB_RADIUS,t,radius,ivalid); pblock->GetValue(PB_RADIUS2,t,radius2,ivalid); pblock->GetValue(PB_ROTATION,t,rotation,ivalid); pblock->GetValue(PB_TWIST,t,twist,ivalid); pblock->GetValue(PB_SEGMENTS,t,segs,ivalid); pblock->GetValue(PB_SIDES,t,sides,ivalid); pblock->GetValue(PB_SMOOTH,t,smooth,ivalid); pblock->GetValue(PB_PIESLICE1,t,pie1,ivalid); pblock->GetValue(PB_PIESLICE2,t,pie2,ivalid); pblock->GetValue(PB_SLICEON,t,doPie,ivalid); pblock->GetValue(PB_GENUVS,t,genUVs,ivalid); LimitValue( radius, MIN_RADIUS, MAX_RADIUS ); LimitValue( radius2, MIN_RADIUS, MAX_RADIUS ); LimitValue( segs, MIN_SEGMENTS, MAX_SEGMENTS ); LimitValue( sides, MIN_SIDES, MAX_SIDES ); // Convert doPie to a 0 or 1 value since it is used in arithmetic below // Controllers can give it non- 0 or 1 values doPie = doPie ? 1 : 0; // We do the torus backwards from the cylinder pie1 = -pie1; pie2 = -pie2; // Make pie2 < pie1 and pie1-pie2 < TWOPI while (pie1 < pie2) pie1 += TWOPI; while (pie1 > pie2+TWOPI) pie1 -= TWOPI; if (pie1==pie2) totalPie = TWOPI; else totalPie = pie1-pie2; if (doPie) { segs++; //*** O.Z. fix for bug 240436 delta = totalPie/(float)(segs-1); startAng = pie2; } else { delta = (float)2.0*PI/(float)segs; } delta2 = (float)2.0*PI/(float)sides; if (TestAFlag(A_PLUGIN1)) startAng -= HALFPI; int nverts; int nfaces; if (doPie) { nverts = sides*segs + 2; nfaces = 2*sides*segs; } else { nverts = sides*segs; nfaces = 2*sides*segs; } mesh.setNumVerts(nverts); mesh.setNumFaces(nfaces); mesh.setSmoothFlags(smooth); if (genUVs) { if (doPie) { mesh.setNumTVerts((sides+1)*segs+2); mesh.setNumTVFaces(2*sides*segs); } else { mesh.setNumTVerts((sides+1)*(segs+1)); mesh.setNumTVFaces(2*sides*segs); } } else { mesh.setNumTVerts(0); mesh.setNumTVFaces(0); } ang = startAng; // make verts for(ix=0; ix<segs; ix++) { sinang = (float)sin(ang); cosang = (float)cos(ang); ang2 = rotation + twist * float(ix+1)/float(segs); for (jx = 0; jx<sides; jx++) { sinang2 = (float)sin(ang2); cosang2 = (float)cos(ang2); rt = radius+radius2*cosang2; p.x = rt*cosang; p.y = -rt*sinang; p.z = radius2*sinang2; mesh.setVert(nv++, p); ang2 += delta2; } ang += delta; } if (doPie) { p.x = radius * (float)cos(startAng); p.y = -radius * (float)sin(startAng); p.z = 0.0f; mesh.setVert(nv++, p); ang -= delta; p.x = radius * (float)cos(ang); p.y = -radius * (float)sin(ang); p.z = 0.0f; mesh.setVert(nv++, p); } // Make faces BOOL usePhysUVs = GetUsePhysicalScaleUVs(); BitArray startSliceFaces; BitArray endSliceFaces; if (usePhysUVs) { startSliceFaces.SetSize(mesh.numFaces); endSliceFaces.SetSize(mesh.numFaces); } /* Make midsection */ for(ix=0; ix<segs-doPie; ++ix) { jx=ix*sides; for (kx=0; kx<sides; ++kx) { na = jx+kx; nb = (ix==(segs-1))?kx:na+sides; nd = (kx==(sides-1))? jx : na+1; nc = nb+nd-na; DWORD grp = 0; if (smooth==SMOOTH_SIDES) { if (kx==sides-1 && (sides&1)) { grp = (1<<2); } else { grp = (kx&1) ? (1<<0) : (1<<1); } } else if (smooth==SMOOTH_STRIPES) { if (ix==segs-1 && (segs&1)) { grp = (1<<2); } else { grp = (ix&1) ? (1<<0) : (1<<1); } } else if (smooth > 0) { grp = 1; } mesh.faces[nf].setEdgeVisFlags(0,1,1); mesh.faces[nf].setSmGroup(grp); mesh.faces[nf].setMatID(0); mesh.faces[nf++].setVerts( na,nc,nb); mesh.faces[nf].setEdgeVisFlags(1,1,0); mesh.faces[nf].setSmGroup(grp); mesh.faces[nf].setMatID(0); mesh.faces[nf++].setVerts(na,nd,nc); } } if (doPie) { na = nv -2; for(ix=0; ix<sides; ++ix) { nb = ix; nc = (ix==(sides-1))?0:ix+1; mesh.faces[nf].setEdgeVisFlags(0,1,0); mesh.faces[nf].setSmGroup((1<<3)); mesh.faces[nf].setMatID(1); if (usePhysUVs) startSliceFaces.Set(nf); mesh.faces[nf++].setVerts(na,nc,nb); } na = nv -1; jx = sides*(segs-1); for(ix=0; ix<sides; ++ix) { nb = jx+ix; nc = (ix==(sides-1))?jx:nb+1; mesh.faces[nf].setEdgeVisFlags(0,1,0); mesh.faces[nf].setSmGroup((1<<3)); mesh.faces[nf].setMatID(2); if (usePhysUVs) endSliceFaces.Set(nf); mesh.faces[nf++].setVerts(na,nb,nc); } } // UVWs ------------------- if (genUVs) { float uScale = usePhysUVs ? ((float) 2.0f * PI * radius) : 1.0f; float vScale = usePhysUVs ? ((float) 2.0f * PI * radius2) : 1.0f; if (doPie) { float pieScale = float(totalPie/(2.0*PI)); uScale *= float(pieScale); } nv=0; for(ix=0; ix<=segs-doPie; ix++) { for (jx=0; jx<=sides; jx++) { if (usePhysUVs) mesh.setTVert(nv++,uScale*(1.0f - float(ix)/float(segs-doPie)),vScale*float(jx)/float(sides),0.0f); else mesh.setTVert(nv++,float(jx)/float(sides),float(ix)/float(segs),0.0f); } } int pie1 = 0; int pie2 = 0; if (doPie) { pie1 = nv; if (usePhysUVs) mesh.setTVert(nv++,0.0f,vScale*0.5f,0.0f); else mesh.setTVert(nv++,0.5f,1.0f,0.0f); pie2 = nv; if (usePhysUVs) mesh.setTVert(nv++,uScale*0.5f,vScale*0.0f,0.0f); else mesh.setTVert(nv++,1.0f,0.5f,0.0f); } nf=0; for(ix=0; ix<segs-doPie; ix++) { na = ix*(sides+1); nb = (ix+1)*(sides+1); for (jx=0; jx<sides; jx++) { mesh.tvFace[nf++].setTVerts(na,nb+1,nb); mesh.tvFace[nf++].setTVerts(na,na+1,nb+1); na++; nb++; } } if (doPie) { if (usePhysUVs) { Matrix3 tm = RotateZMatrix(startAng) * RotateXMatrix(float(-PI/2.0)); tm.Scale(Point3(-1.0f, 1.0f, 1.0f)); MakeMeshCapTexture(mesh, tm, startSliceFaces, usePhysUVs); tm = RotateZMatrix(ang) * RotateXMatrix(float(-PI/2.0)); MakeMeshCapTexture(mesh, tm, endSliceFaces, usePhysUVs); } else { for (jx=0; jx<sides; jx++) { mesh.tvFace[nf++].setTVerts(pie1,jx+1,jx); } nb = (sides+1)*(segs-1); for (jx=0; jx<sides; jx++) { mesh.tvFace[nf++].setTVerts(pie2,nb,nb+1); nb++; } } } } mesh.InvalidateTopologyCache(); }
Object * BuildNURBSTorus(float radius, float radius2, BOOL sliceon, float pie1, float pie2, BOOL genUVs) { NURBSSet nset; Point3 origin(0,0,0); Point3 symAxis(0,0,1); Point3 refAxis(0,1,0); float startAngle = 0.0f; float endAngle = TWOPI; if (sliceon && pie1 != pie2) { float sweep = pie2-pie1; if (sweep <= 0.0f) sweep += TWOPI; refAxis = Point3(Point3(0,1,0) * RotateZMatrix(pie1)); endAngle = sweep; } // first the main surface NURBSCVSurface *surf = new NURBSCVSurface(); nset.AppendObject(surf); surf->SetGenerateUVs(genUVs); surf->SetTextureUVs(0, 0, Point2(0.0f, 0.0f)); surf->SetTextureUVs(0, 1, Point2(0.0f, 1.0f)); surf->SetTextureUVs(0, 2, Point2(1.0f, 0.0f)); surf->SetTextureUVs(0, 3, Point2(1.0f, 1.0f)); surf->FlipNormals(TRUE); surf->Renderable(TRUE); TCHAR bname[80]; TCHAR sname[80]; _tcscpy(bname, GetString(IDS_RB_TORUS)); _stprintf(sname, _T("%s%s"), bname, GetString(IDS_CT_SURF)); surf->SetName(sname); if (sliceon && pie1 != pie2) { GenNURBSTorusSurface(radius, radius2, origin, symAxis, refAxis, startAngle, endAngle, -PI, PI, TRUE, *surf); // now create caps on the ends NURBSCapSurface *cap0 = new NURBSCapSurface(); nset.AppendObject(cap0); cap0->SetGenerateUVs(genUVs); cap0->SetParent(0); cap0->SetEdge(2); cap0->FlipNormals(FALSE); cap0->Renderable(TRUE); TCHAR sname[80]; _stprintf(sname, _T("%s%s%02d"), bname, GetString(IDS_CT_CAP), 0); cap0->SetName(sname); NURBSCapSurface *cap1 = new NURBSCapSurface(); nset.AppendObject(cap1); cap1->SetGenerateUVs(genUVs); cap1->SetParent(0); cap1->SetEdge(3); cap1->FlipNormals(TRUE); cap1->Renderable(TRUE); _stprintf(sname, _T("%s%s%02d"), bname, GetString(IDS_CT_CAP), 1); cap1->SetName(sname); } else { GenNURBSTorusSurface(radius, radius2, origin, symAxis, refAxis, startAngle, endAngle, -PI, PI, FALSE, *surf); } Matrix3 mat; mat.IdentityMatrix(); Object *ob = CreateNURBSObject(NULL, &nset, mat); return ob; }
void RSBase3D::AddRotationZ(float theta) { mat=MatrixMult(RotateZMatrix(theta),mat); GetDirectionVectors(); }