/** * Computes if triangle p1,p2,p3 is overlapped with triangle q1,q2,q3. * @param normal normal of the triangle p1,p2,p3 * @param p1 point of first triangle * @param p2 point of first triangle * @param p3 point of first triangle * @param q1 point of second triangle * @param q2 point of second triangle * @param q3 point of second triangle * @return if there is overlapping between both triangles */ bool BOP_overlap(MT_Vector3 normal, MT_Point3 p1, MT_Point3 p2, MT_Point3 p3, MT_Point3 q1, MT_Point3 q2, MT_Point3 q3) { MT_Vector3 p1p2 = p2-p1; MT_Plane3 plane1(p1p2.cross(normal),p1); MT_Vector3 p2p3 = p3-p2; MT_Plane3 plane2(p2p3.cross(normal),p2); MT_Vector3 p3p1 = p1-p3; MT_Plane3 plane3(p3p1.cross(normal),p3); BOP_TAG tag1 = BOP_createTAG(BOP_classify(q1,plane1)); BOP_TAG tag2 = BOP_createTAG(BOP_classify(q1,plane2)); BOP_TAG tag3 = BOP_createTAG(BOP_classify(q1,plane3)); BOP_TAG tagQ1 = BOP_createTAG(tag1,tag2,tag3); if (tagQ1 == IN_IN_IN) return true; tag1 = BOP_createTAG(BOP_classify(q2,plane1)); tag2 = BOP_createTAG(BOP_classify(q2,plane2)); tag3 = BOP_createTAG(BOP_classify(q2,plane3)); BOP_TAG tagQ2 = BOP_createTAG(tag1,tag2,tag3); if (tagQ2 == IN_IN_IN) return true; tag1 = BOP_createTAG(BOP_classify(q3,plane1)); tag2 = BOP_createTAG(BOP_classify(q3,plane2)); tag3 = BOP_createTAG(BOP_classify(q3,plane3)); BOP_TAG tagQ3 = BOP_createTAG(tag1,tag2,tag3); if (tagQ3 == IN_IN_IN) return true; if ((tagQ1 & OUT_OUT_OUT) == 0 && (tagQ2 & OUT_OUT_OUT) == 0 && (tagQ3 & OUT_OUT_OUT) == 0) return true; else return false; }
BaseIF* makeVane(const Real& thick, const RealVect& normal, const Real& innerRadius, const Real& outerRadius, const Real& offset, const Real& height) { RealVect zero(D_DECL(0.0,0.0,0.0)); RealVect xAxis(D_DECL(1.0,0.0,0.0)); bool inside = true; Vector<BaseIF*> vaneParts; // Each side of the vane (infinite) RealVect normal1(normal); RealVect point1(D_DECL(offset+height/2.0,-thick/2.0,0.0)); PlaneIF plane1(normal1,point1,inside); vaneParts.push_back(&plane1); RealVect normal2(-normal); RealVect point2(D_DECL(offset+height/2.0,thick/2.0,0.0)); PlaneIF plane2(normal2,point2,inside); vaneParts.push_back(&plane2); // Make sure we only get something to the right of the origin RealVect normal3(D_DECL(0.0,0.0,1.0)); RealVect point3(D_DECL(0.0,0.0,0.0)); PlaneIF plane3(normal3,point3,inside); vaneParts.push_back(&plane3); // Cut off the top and bottom RealVect normal4(D_DECL(1.0,0.0,0.0)); RealVect point4(D_DECL(offset,0.0,0.0)); PlaneIF plane4(normal4,point4,inside); vaneParts.push_back(&plane4); RealVect normal5(D_DECL(-1.0,0.0,0.0)); RealVect point5(D_DECL(offset+height,0.0,0.0)); PlaneIF plane5(normal5,point5,inside); vaneParts.push_back(&plane5); // The outside of the inner cylinder TiltedCylinderIF inner(innerRadius,xAxis,zero,!inside); vaneParts.push_back(&inner); // The inside of the outer cylinder TiltedCylinderIF outer(outerRadius,xAxis,zero,inside); vaneParts.push_back(&outer); IntersectionIF* vane = new IntersectionIF(vaneParts); return vane; }
void cGameCell::sPortal::CalcEdgePlanes( cGameCell* pParent ) { int curr, next; for( curr=0; curr<m_nVerts; curr++ ) { next = (curr+1) % m_nVerts; point3 edgeVec = pParent->m_ptList[ m_vList[next].m_ind ] - pParent->m_ptList[ m_vList[curr].m_ind ]; point3 edgeNorm = m_plane.n ^ edgeVec; edgeNorm.Normalize(); plane3 edgePlane = plane3( edgeNorm, pParent->m_ptList[ m_vList[curr].m_ind ] ); m_edgePlanes.push_back( edgePlane ); } }
void buildAndRenderScene(Scene &scene, Camera &camera, RenderTarget &renderTarget) { // Build scene AmbientLight ambientLight(Color::white); PointLight light1(Vector3D(50.0, 70.0, 0.0)); PointLight light2(Vector3D(50.0, 70.0, 200.0)); Torus sphere1(10, 4, Vector3D(0.0, 20.0, 100.0)); PhongMaterial material1(Color::red); Sphere sphere2(10, Vector3D(0.0, 45.0, 100.0)); PhongMaterial material2(Color::green); Sphere sphere3(10, Vector3D(35.0, 20.0, 100.0)); PhongMaterial material3(Color::blue); Plane plane1(Vector3D(0, 0, 0), Vector3D(0.0, 1.0, 0.0)); PhongMaterial material4(Color(0.0, 1.0, 1.0)); Plane plane2(Vector3D(-100, 0, 0), Vector3D(1.0, 0.0, 0.0)); PhongMaterial material5(Color(1.0, 0.0, 1.0)); Plane plane3(Vector3D(0, 0, 500), Vector3D(0.0, 0.0, -1.0)); PhongMaterial material6(Color(1.0, 1.0, 0.0)); sphere1.setMaterial(&material1); sphere2.setMaterial(&material2); sphere3.setMaterial(&material3); plane1.setMaterial(&material4); plane2.setMaterial(&material5); plane3.setMaterial(&material6); scene.addObject(&sphere1); scene.addObject(&sphere2); scene.addObject(&sphere3); scene.addObject(&plane1); scene.addObject(&plane2); scene.addObject(&plane3); scene.addLight(&light1); scene.addLight(&light2); scene.setAmbientLight(&ambientLight); // Render scene camera.computeFrame(); camera.renderScene(scene, renderTarget); renderTarget.update(); }
bbox3::bbox3() { min = point3( 50000, 50000, 50000 ); max = point3( -50000, -50000, -50000 ); // top, bottom, back, front, right, left planeList[0] = plane3( point3( 0.f, 1.f, 0.f ), max ); planeList[1] = plane3( point3( 0.f,-1.f, 0.f ), min ); planeList[2] = plane3( point3( 0.f, 0.f, 1.f ), max ); planeList[3] = plane3( point3( 0.f, 0.f,-1.f ), min ); planeList[4] = plane3( point3( 1.f, 0.f, 0.f ), max ); planeList[5] = plane3( point3(-1.f, 0.f, 0.f ), min ); plane3 planeList[6]; }
BaseIF* makeVane(const Real& thick, const RealVect& normal, const Real& innerRadius, const Real& outerRadius, const Real& offset, const Real& height, const Real& angle) { RealVect zeroVect(D_DECL(0.0,0.0,0.0)); RealVect xAxis(D_DECL(1.0,0.0,0.0)); bool inside = true; Vector<BaseIF*> vaneParts; Real sinTheta = sin(angle); #if CH_SPACEDIM == 3 Real cosTheta = cos(angle); // Each side of the vane (infinite) // rotate the normal around x-axis RealVect normal1(D_DECL(normal[0],cosTheta*normal[1]-sinTheta*normal[2],sinTheta*normal[1]+cosTheta*normal[2])); // rotate point on top of vane around x-axis RealVect point(D_DECL(offset+height/2.0,-thick/2.0,0.0)); RealVect point1(D_DECL(point[0],cosTheta*point[1]-sinTheta*point[2],sinTheta*point[1]+cosTheta*point[2])); PlaneIF plane1(normal1,point1,inside); vaneParts.push_back(&plane1); RealVect normal2(-normal1); // rotate point on bottom (-point[2] of vane around x-axis RealVect point2(D_DECL(point[0],-cosTheta*point[1]-sinTheta*point[2],-sinTheta*point[1]+cosTheta*point[2])); PlaneIF plane2(normal2,point2,inside); vaneParts.push_back(&plane2); #endif // Make sure we only get something to the right of the origin RealVect normal3(D_DECL(0.0,-sinTheta,cosTheta)); RealVect point3(D_DECL(0.0,0.0,0.0)); PlaneIF plane3(normal3,point3,inside); vaneParts.push_back(&plane3); // Cut off the top and bottom RealVect normal4(D_DECL(1.0,0.0,0.0)); RealVect point4(D_DECL(offset,0.0,0.0)); PlaneIF plane4(normal4,point4,inside); vaneParts.push_back(&plane4); RealVect normal5(D_DECL(-1.0,0.0,0.0)); RealVect point5(D_DECL(offset+height,0.0,0.0)); PlaneIF plane5(normal5,point5,inside); vaneParts.push_back(&plane5); // The outside of the inner cylinder TiltedCylinderIF inner(innerRadius,xAxis,zeroVect,!inside); vaneParts.push_back(&inner); // The inside of the outer cylinder TiltedCylinderIF outer(outerRadius,xAxis,zeroVect,inside); vaneParts.push_back(&outer); IntersectionIF* vane = new IntersectionIF(vaneParts); return vane; }
/** * Triangulates faceB using edges of faceA that both are complanars. * @param mesh mesh that contains the faces, edges and vertices * @param facesB set of faces from object B * @param faceA face from object A * @param faceB face from object B * @param invert indicates if faceA has priority over faceB */ void BOP_intersectCoplanarFaces(BOP_Mesh* mesh, BOP_Faces* facesB, BOP_Face* faceA, BOP_Face* faceB, bool invert) { unsigned int oldSize = facesB->size(); unsigned int originalFaceB = faceB->getOriginalFace(); MT_Point3 p1 = mesh->getVertex(faceA->getVertex(0))->getPoint(); MT_Point3 p2 = mesh->getVertex(faceA->getVertex(1))->getPoint(); MT_Point3 p3 = mesh->getVertex(faceA->getVertex(2))->getPoint(); MT_Vector3 normal(faceA->getPlane().x(),faceA->getPlane().y(),faceA->getPlane().z()); MT_Vector3 p1p2 = p2-p1; MT_Plane3 plane1((p1p2.cross(normal).normalized()),p1); BOP_Segment sA; sA.m_cfg1 = BOP_Segment::createVertexCfg(1); sA.m_v1 = faceA->getVertex(0); sA.m_cfg2 = BOP_Segment::createVertexCfg(2); sA.m_v2 = faceA->getVertex(1); BOP_intersectCoplanarFaces(mesh,facesB,faceB,sA,plane1,invert); MT_Vector3 p2p3 = p3-p2; MT_Plane3 plane2((p2p3.cross(normal).normalized()),p2); sA.m_cfg1 = BOP_Segment::createVertexCfg(2); sA.m_v1 = faceA->getVertex(1); sA.m_cfg2 = BOP_Segment::createVertexCfg(3); sA.m_v2 = faceA->getVertex(2); if (faceB->getTAG() == BROKEN) { for(unsigned int idxFace = oldSize; idxFace < facesB->size(); idxFace++) { BOP_Face *face = (*facesB)[idxFace]; if (face->getTAG() != BROKEN && originalFaceB == face->getOriginalFace()) BOP_intersectCoplanarFaces(mesh,facesB,face,sA,plane2,invert); } } else { BOP_intersectCoplanarFaces(mesh,facesB,faceB,sA,plane2,invert); } MT_Vector3 p3p1 = p1-p3; MT_Plane3 plane3((p3p1.cross(normal).safe_normalized()),p3); sA.m_cfg1 = BOP_Segment::createVertexCfg(3); sA.m_v1 = faceA->getVertex(2); sA.m_cfg2 = BOP_Segment::createVertexCfg(1); sA.m_v2 = faceA->getVertex(0); if (faceB->getTAG() == BROKEN) { for(unsigned int idxFace = oldSize; idxFace < facesB->size(); idxFace++) { BOP_Face *face = (*facesB)[idxFace]; if (face->getTAG() != BROKEN && originalFaceB == face->getOriginalFace()) BOP_intersectCoplanarFaces(mesh,facesB,face,sA,plane3,invert); } } else { BOP_intersectCoplanarFaces(mesh,facesB,faceB,sA,plane3,invert); } }
int main() try { Point tl(300,50); Simple_window win(tl,1000,800,"My window"); win.wait_for_button(); win.set_label("My window"); // add grid on leftmost 800-by-800 part Lines grid; int x_size = 800; int y_size = 800; for (int i = 100; i<=x_size; i+=100) { grid.add(Point(i,0),Point(i,y_size)); grid.add(Point(0,i),Point(x_size,i)); } win.attach(grid); //win.resize(1000,800); win.wait_for_button(); // make squares on the diagonal red Vector_ref<Graph_lib::Rectangle> vr; for (int i = 0; i<8; ++i) { vr.push_back(new Graph_lib::Rectangle(Point(i*100,i*100),101,101)); vr[vr.size()-1].set_fill_color(Color::red); win.attach(vr[vr.size()-1]); } //win.resize(1000,800); win.wait_for_button(); // place 3 copies of a 200-by-200 image, don't cover the red squares Image plane1(Point(200,0),"pics_and_txt/image.jpg"); plane1.set_mask(Point(200,0),200,200); win.attach(plane1); Image plane2(Point(500,200),"pics_and_txt/image.jpg"); plane2.set_mask(Point(200,0),200,200); win.attach(plane2); Image plane3(Point(100,500),"pics_and_txt/image.jpg"); plane3.set_mask(Point(200,0),200,200); win.attach(plane3); //win.resize(1000,800); win.wait_for_button(); // add a 100-by-100 image, have it move around Image snow(Point(0,0),"pics_and_txt/snow_cpp.gif"); snow.set_mask(Point(110,70),100,100); win.attach(snow); //win.resize(1000,800); win.wait_for_button(); int x = 0; int y = 0; int dx = 0; int dy = 0; while (true) { x = randint(8); y = randint(8); dx = 100*x - snow.point(0).x; dy = 100*y - snow.point(0).y; snow.move(dx,dy); //win.resize(1000,800); win.wait_for_button(); } } catch (exception& e) { cerr << "exception: " << e.what() << endl; keep_window_open(); } catch (...) { cerr << "exception\n"; keep_window_open(); }
cGameCell::cGameCell( cFile& file, int num ) : m_index( num ) { queue<string> tokQueue; SetID( MakeID( c_cellSegment, num ) ); MsgDaemon()->RegObject( GetID(), this ); string tok; do { file.TokenizeNextNCLine( &tokQueue, '#' ); tok = nextTok( tokQueue ); if( tok == "CELL_START" ) { // do nothing } else if( tok == "CELL_END" ) { break; } else if( tok == "PT" ) { point3 pt; // Read in the point tok = nextTok( tokQueue ); pt.x = atof( tok.c_str() ); tok = nextTok( tokQueue ); pt.y = atof( tok.c_str() ); tok = nextTok( tokQueue ); pt.z = atof( tok.c_str() ); // Append it to the list m_ptList.push_back( pt ); } else if( tok == "FACE" ) { tok = nextTok( tokQueue ); int nInd = atoi( tok.c_str() ); // Create the polygon structure to fill sPolygon currPoly; currPoly.m_nVerts = nInd; /** * The next line is the indices. */ file.TokenizeNextNCLine( &tokQueue, '#' ); // Fill in the indices for( int i=0; i< nInd; i++ ) { tok = nextTok( tokQueue ); currPoly.m_vList[i].m_ind = atoi( tok.c_str() ); } // Now we can build the plane. currPoly.m_plane = plane3( m_ptList[currPoly.m_vList[0].m_ind], m_ptList[currPoly.m_vList[1].m_ind], m_ptList[currPoly.m_vList[2].m_ind] ); /** * Next line is the colors */ file.TokenizeNextNCLine( &tokQueue, '#' ); // Fill in the colors for( i=0; i< nInd; i++ ) { tok = nextTok( tokQueue ); sscanf( tok.c_str(), "%x", &currPoly.m_vList[i].m_col ); } /** * Final line is the texture info. */ file.TokenizeNextNCLine( &tokQueue, '#' ); point3 m, n, p; // First token says whether to auto generate textures // Or explicitly read them. tok = nextTok( tokQueue ); if( tok == "AUTO" ) { // Automatically generate the texture vectors p = (m_ptList[currPoly.m_vList[0].m_ind]); tok = nextTok( tokQueue ); currPoly.m_texID = atoi( tok.c_str() ); tok = nextTok( tokQueue ); float mScale = atof( tok.c_str() ); tok = nextTok( tokQueue ); float nScale = atof( tok.c_str() ); // Run tests to figure out which way the plane faces if( point3::i == currPoly.m_plane.n || -1*point3::i == currPoly.m_plane.n ) { // plane points in the +/-x direction m.Assign(0,0,1); n.Assign(0,1,0); } else if( point3::j == currPoly.m_plane.n || -1*point3::j == currPoly.m_plane.n ) { // plane points in the +/-y direction m.Assign(0,0,1); n.Assign(1,0,0); } else if( point3::k == currPoly.m_plane.n || -1*point3::k == currPoly.m_plane.n ) { // plane points in the +/-z direction m.Assign(1,0,0); n.Assign(0,1,0); } // No easy guess... just estimate using the first two points as one vector // and the cross as the other. else { m = m_ptList[currPoly.m_vList[1].m_ind] - m_ptList[currPoly.m_vList[0].m_ind]; m.Normalize(); n = m ^ currPoly.m_plane.n; } // scale the vectors by the provided scaling values. m *= mScale; n *= nScale; } else if( tok == "EXP" ) { // Explicit tex-gen. texture ID and then 9 floats (p,m,n). tok = nextTok( tokQueue ); currPoly.m_texID = atoi( tok.c_str() ); // P tok = nextTok( tokQueue ); p.x = atof( tok.c_str() ); tok = nextTok( tokQueue ); p.y = atof( tok.c_str() ); tok = nextTok( tokQueue ); p.z = atof( tok.c_str() ); // M tok = nextTok( tokQueue ); m.x = atof( tok.c_str() ); tok = nextTok( tokQueue ); m.y = atof( tok.c_str() ); tok = nextTok( tokQueue ); m.z = atof( tok.c_str() ); // N tok = nextTok( tokQueue ); n.x = atof( tok.c_str() ); tok = nextTok( tokQueue ); n.y = atof( tok.c_str() ); tok = nextTok( tokQueue ); n.z = atof( tok.c_str() ); } else throw cGameError( "Bad texture gen token" ); float mMag = m.Mag(); m /= mMag; float nMag = n.Mag(); n /= nMag; // We have the n,m,p vectors; let's generate the coordinates. for( i=0; i<nInd; i++ ) { point3 pt = m_ptList[currPoly.m_vList[i].m_ind] - p; float u = (pt * m); float v = (pt * n); currPoly.m_vList[i].m_u = u / mMag; currPoly.m_vList[i].m_v = v / nMag; } // Add the poly m_polyList.push_back( currPoly ); } else if( 0 == tok.compare( "PORTAL" ) ) { tok = nextTok( tokQueue ); int other = atoi( tok.c_str() ); tok = nextTok( tokQueue ); int nInd = atoi( tok.c_str() ); // Create the polygon structure to fill sPortal currPortal; currPortal.m_nVerts = nInd; // first # in the file is 1, here is 0 currPortal.m_other = MakeID( c_cellSegment, other - 1); // Fill in the indices for( int i=0; i< nInd; i++ ) { tok = nextTok( tokQueue ); currPortal.m_vList[i].m_ind = atoi( tok.c_str() ); } currPortal.m_plane = plane3( m_ptList[currPortal.m_vList[0].m_ind], m_ptList[currPortal.m_vList[1].m_ind], m_ptList[currPortal.m_vList[2].m_ind] ); // build the edge planes for this portal currPortal.CalcEdgePlanes( this ); // Add the poly m_portalList.push_back( currPortal ); } } while( 1 ); }