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; }
Object* BuildNURBSPrism(float side1, float side2, float side3, float height, int genUVs) { float s13len=side1*side3; float theta = (float)acos((side2*side2 - side1*side1 - side3*side3)/(-2.0f*s13len)); int prism_faces[5][4] = {{0, 1, 2, 2}, // bottom {1, 0, 4, 3}, // front {2, 1, 5, 4}, // left {0, 2, 3, 5}, // right {4, 3, 5, 5}};// top Point3 prism_verts[6] ={Point3(0.0f, 0.0f, 0.0f), Point3(side1, 0.0f, 0.0f), Point3(side3*(float)cos(theta), side3*(float)sin(theta), 0.0f), Point3(0.0f, 0.0f, height), Point3(side1, 0.0f, height), Point3(side3*(float)cos(theta), side3*(float)sin(theta), height)}; NURBSSet nset; for (int face = 0; face < 5; face++) { Point3 bl = prism_verts[prism_faces[face][0]]; Point3 br = prism_verts[prism_faces[face][1]]; Point3 tl = prism_verts[prism_faces[face][2]]; Point3 tr = prism_verts[prism_faces[face][3]]; NURBSCVSurface *surf = new NURBSCVSurface(); nset.AppendObject(surf); surf->SetUOrder(4); surf->SetVOrder(4); surf->SetNumCVs(4, 4); surf->SetNumUKnots(8); surf->SetNumVKnots(8); Point3 top, bot; for (int r = 0; r < 4; r++) { top = tl + (((float)r/3.0f) * (tr - tl)); bot = bl + (((float)r/3.0f) * (br - bl)); for (int c = 0; c < 4; c++) { NURBSControlVertex ncv; ncv.SetPosition(0, bot + (((float)c/3.0f) * (top - bot))); ncv.SetWeight(0, 1.0f); surf->SetCV(r, c, ncv); } } for (int k = 0; k < 4; k++) { surf->SetUKnot(k, 0.0); surf->SetVKnot(k, 0.0); surf->SetUKnot(k + 4, 1.0); surf->SetVKnot(k + 4, 1.0); } surf->Renderable(TRUE); surf->SetGenerateUVs(genUVs); if (height > 0.0f) surf->FlipNormals(TRUE); else surf->FlipNormals(FALSE); float sum = side1 + side2 + side3; float s1 = side1/sum; float s3 = 1.0f - side3/sum; switch(face) { case 0: surf->SetTextureUVs(0, 0, Point2(0.5f, 0.0f)); surf->SetTextureUVs(0, 1, Point2(0.5f, 0.0f)); surf->SetTextureUVs(0, 2, Point2(1.0f, 1.0f)); surf->SetTextureUVs(0, 3, Point2(0.0f, 1.0f)); break; case 1: surf->SetTextureUVs(0, 0, Point2(s1, 1.0f)); surf->SetTextureUVs(0, 1, Point2(0.0f, 1.0f)); surf->SetTextureUVs(0, 2, Point2(s1, 0.0f)); surf->SetTextureUVs(0, 3, Point2(0.0f, 0.0f)); break; case 2: surf->SetTextureUVs(0, 0, Point2(s3, 1.0f)); surf->SetTextureUVs(0, 1, Point2(s1, 1.0f)); surf->SetTextureUVs(0, 2, Point2(s3, 0.0f)); surf->SetTextureUVs(0, 3, Point2(s1, 0.0f)); break; case 3: surf->SetTextureUVs(0, 0, Point2(1.0f, 1.0f)); surf->SetTextureUVs(0, 1, Point2(s3, 1.0f)); surf->SetTextureUVs(0, 2, Point2(1.0f, 0.0f)); surf->SetTextureUVs(0, 3, Point2(s3, 0.0f)); break; case 4: surf->SetTextureUVs(0, 0, Point2(0.5f, 1.0f)); surf->SetTextureUVs(0, 1, Point2(0.5f, 1.0f)); surf->SetTextureUVs(0, 2, Point2(1.0f, 0.0f)); surf->SetTextureUVs(0, 3, Point2(0.0f, 0.0f)); break; } TCHAR bname[80]; _stprintf(bname, _T("%s%02d"), GetString(IDS_CT_SURF), face); surf->SetName(bname); } #define F(s1, s2, s1r, s1c, s2r, s2c) \ fuse.mSurf1 = (s1); \ fuse.mSurf2 = (s2); \ fuse.mRow1 = (s1r); \ fuse.mCol1 = (s1c); \ fuse.mRow2 = (s2r); \ fuse.mCol2 = (s2c); \ nset.mSurfFuse.Append(1, &fuse); NURBSFuseSurfaceCV fuse; // Bottom(0) to Front (1) F(0, 1, 3, 0, 0, 0); F(0, 1, 2, 0, 1, 0); F(0, 1, 1, 0, 2, 0); F(0, 1, 0, 0, 3, 0); // Bottom(0) to Left (2) F(0, 2, 3, 0, 3, 0); F(0, 2, 3, 1, 2, 0); F(0, 2, 3, 2, 1, 0); F(0, 2, 3, 3, 0, 0); // Bottom(0) to Right (3) F(0, 3, 0, 0, 0, 0); F(0, 3, 0, 1, 1, 0); F(0, 3, 0, 2, 2, 0); F(0, 3, 0, 3, 3, 0); // Top(4) to Front (1) F(4, 1, 3, 0, 3, 3); F(4, 1, 2, 0, 2, 3); F(4, 1, 1, 0, 1, 3); F(4, 1, 0, 0, 0, 3); // Top(4) to Left (2) F(4, 2, 0, 0, 3, 3); F(4, 2, 0, 1, 2, 3); F(4, 2, 0, 2, 1, 3); F(4, 2, 0, 3, 0, 3); // Top(4) to Right (3) F(4, 3, 3, 0, 0, 3); F(4, 3, 3, 1, 1, 3); F(4, 3, 3, 2, 2, 3); F(4, 3, 3, 3, 3, 3); // Front(1) to Left (2) F(1, 2, 0, 1, 3, 1); F(1, 2, 0, 2, 3, 2); // Left(2) to Right (3) F(2, 3, 0, 1, 3, 1); F(2, 3, 0, 2, 3, 2); // Right(3) to Front (1) F(3, 1, 0, 1, 3, 1); F(3, 1, 0, 2, 3, 2); // Fuse the triangles together for (int i = 1; i < 4; i++) { F(0, 0, 0, 3, i, 3); F(4, 4, 0, 3, i, 3); } Matrix3 mat; mat.IdentityMatrix(); Object *obj = CreateNURBSObject(NULL, &nset, mat); return obj; }
Object* BuildNURBSPyramid(float width, float depth, float height, int genUVs) { int pyramid_faces[5][4] = { {0, 1, 2, 3}, // bottom {2, 3, 4, 4}, // back {1, 0, 4, 4}, // front {3, 1, 4, 4}, // left {0, 2, 4, 4}};// right Point3 pyramid_verts[5] = { Point3(-0.5, -0.5, 0.0), Point3( 0.5, -0.5, 0.0), Point3(-0.5, 0.5, 0.0), Point3( 0.5, 0.5, 0.0), Point3( 0.0, 0.0, 1.0)}; NURBSSet nset; for (int face = 0; face < 5; face++) { Point3 bl = pyramid_verts[pyramid_faces[face][0]]; Point3 br = pyramid_verts[pyramid_faces[face][1]]; Point3 tl = pyramid_verts[pyramid_faces[face][2]]; Point3 tr = pyramid_verts[pyramid_faces[face][3]]; Matrix3 size; size.IdentityMatrix(); Point3 lwh(width, depth, height); size.Scale(lwh); bl = bl * size; br = br * size; tl = tl * size; tr = tr * size; NURBSCVSurface *surf = new NURBSCVSurface(); nset.AppendObject(surf); surf->SetUOrder(4); surf->SetVOrder(4); surf->SetNumCVs(4, 4); surf->SetNumUKnots(8); surf->SetNumVKnots(8); Point3 top, bot; for (int r = 0; r < 4; r++) { top = tl + (((float)r/3.0f) * (tr - tl)); bot = bl + (((float)r/3.0f) * (br - bl)); for (int c = 0; c < 4; c++) { NURBSControlVertex ncv; ncv.SetPosition(0, bot + (((float)c/3.0f) * (top - bot))); ncv.SetWeight(0, 1.0f); surf->SetCV(r, c, ncv); } } for (int k = 0; k < 4; k++) { surf->SetUKnot(k, 0.0); surf->SetVKnot(k, 0.0); surf->SetUKnot(k + 4, 1.0); surf->SetVKnot(k + 4, 1.0); } surf->Renderable(TRUE); surf->SetGenerateUVs(genUVs); if (height > 0.0f) surf->FlipNormals(TRUE); else surf->FlipNormals(FALSE); switch(face) { case 0: // bottom surf->SetTextureUVs(0, 0, Point2(1.0f, 0.0f)); surf->SetTextureUVs(0, 1, Point2(0.0f, 0.0f)); surf->SetTextureUVs(0, 2, Point2(1.0f, 1.0f)); surf->SetTextureUVs(0, 3, Point2(0.0f, 1.0f)); break; default: // sides surf->SetTextureUVs(0, 0, Point2(0.5f, 1.0f)); surf->SetTextureUVs(0, 1, Point2(0.5f, 1.0f)); surf->SetTextureUVs(0, 2, Point2(0.0f, 0.0f)); surf->SetTextureUVs(0, 3, Point2(1.0f, 0.0f)); break; } TCHAR bname[80]; _stprintf(bname, _T("%s%02d"), GetString(IDS_CT_SURF), face); surf->SetName(bname); } #define F(s1, s2, s1r, s1c, s2r, s2c) \ fuse.mSurf1 = (s1); \ fuse.mSurf2 = (s2); \ fuse.mRow1 = (s1r); \ fuse.mCol1 = (s1c); \ fuse.mRow2 = (s2r); \ fuse.mCol2 = (s2c); \ nset.mSurfFuse.Append(1, &fuse); NURBSFuseSurfaceCV fuse; // Fuse the degenerate peaks for (int i = 1; i < 5; i++) { for (int j = 1; j < 4; j++) { F(i, i, 0, 3, j, 3); } } // Fuse the peaks together F(1, 2, 0, 3, 0, 3); F(1, 3, 0, 3, 0, 3); F(1, 4, 0, 3, 0, 3); // Bottom(0) to Back (1) F(0, 1, 3, 3, 3, 0); F(0, 1, 2, 3, 2, 0); F(0, 1, 1, 3, 1, 0); F(0, 1, 0, 3, 0, 0); // Bottom(0) to Front (2) F(0, 2, 0, 0, 3, 0); F(0, 2, 1, 0, 2, 0); F(0, 2, 2, 0, 1, 0); F(0, 2, 3, 0, 0, 0); // Bottom(0) to Left (3) F(0, 3, 3, 0, 3, 0); F(0, 3, 3, 1, 2, 0); F(0, 3, 3, 2, 1, 0); F(0, 3, 3, 3, 0, 0); // Bottom(0) to Right (4) F(0, 4, 0, 0, 0, 0); F(0, 4, 0, 1, 1, 0); F(0, 4, 0, 2, 2, 0); F(0, 4, 0, 3, 3, 0); // Front (2) to Right (4) F(2, 4, 3, 1, 0, 1); F(2, 4, 3, 2, 0, 2); // Right (4) to Back (1) F(4, 1, 3, 1, 0, 1); F(4, 1, 3, 2, 0, 2); // Back (1) to Left (3) F(1, 3, 3, 1, 0, 1); F(1, 3, 3, 2, 0, 2); // Left (3) to Front (2) F(3, 2, 3, 1, 0, 1); F(3, 2, 3, 2, 0, 2); Matrix3 mat; mat.IdentityMatrix(); Object *obj = CreateNURBSObject(NULL, &nset, mat); return obj; }