Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- EXPORT GameApi::BO GameApi::BooleanOps::cube(GameApi::EveryApi &ev,
- float start_x, float end_x,
- float start_y, float end_y,
- float start_z, float end_z,
- int split_x, int split_y)
- {
- P mesh = ev.polygon_api.cube(start_x, end_x, start_y, end_y, start_z, end_z);
- P mesh2 = ev.polygon_api.splitquads(mesh, split_x, split_y);
- O bools = ev.volume_api.cube(start_x, end_x, start_y, end_y, start_z, end_z);
- FD fd = ev.dist_api.cube(start_x, end_x, start_y, end_y, start_z, end_z);
- //CT cutter = ev.cutter_api.distance_cut(fd);
- return create_bo(mesh2, bools, fd);
- }
- EXPORT GameApi::BO GameApi::BooleanOps::sphere(GameApi::EveryApi &ev, PT center, float radius, int numfaces1, int numfaces2)
- {
- P mesh = ev.polygon_api.sphere(center, radius, numfaces1, numfaces2);
- O bools = ev.volume_api.sphere(center, radius);
- FD fd = ev.dist_api.sphere(center, radius);
- return create_bo(mesh, bools, fd);
- }
- EXPORT GameApi::BO GameApi::BooleanOps::or_elem(GameApi::EveryApi &ev, GameApi::BO obj, GameApi::BO obj2)
- {
- ::EnvImpl *env = ::EnvImpl::Environment(&e);
- BO_Impl obj_i = env->boolean_ops[obj.id];
- BO_Impl obj2_i = env->boolean_ops[obj2.id];
- P mesh = ev.polygon_api.or_elem(obj_i.mesh, obj2_i.mesh);
- O bools = ev.volume_api.max_op(obj_i.bools, obj2_i.bools);
- FD fd = ev.dist_api.min(obj_i.fd, obj2_i.fd);
- return create_bo(mesh, bools, fd);
- }
- EXPORT GameApi::BO GameApi::BooleanOps::and_not(GameApi::EveryApi &ev, GameApi::BO obj, GameApi::BO obj2)
- {
- ::EnvImpl *env = ::EnvImpl::Environment(&e);
- BO_Impl obj_i = env->boolean_ops[obj.id];
- BO_Impl obj2_i = env->boolean_ops[obj2.id];
- CT cutter = ev.cutter_api.distance_cut(obj_i.fd);
- CT cutter2 = ev.cutter_api.distance_cut(obj2_i.fd);
- P mesh = ev.polygon_api.and_not_elem(ev, obj2_i.mesh, obj_i.mesh,
- obj2_i.bools, obj_i.bools,
- cutter2, cutter);
- //P mesh2 = ev.polygon_api.tri_to_quad(mesh);
- O bools = ev.volume_api.andnot_op(obj_i.bools, obj2_i.bools);
- FD fd = ev.dist_api.and_not(obj_i.fd, obj2_i.fd);
- return create_bo(mesh, bools, fd);
- }
- EXPORT GameApi::BO GameApi::BooleanOps::intersect(GameApi::EveryApi &ev, GameApi::BO obj, GameApi::BO obj2)
- {
- ::EnvImpl *env = ::EnvImpl::Environment(&e);
- BO_Impl obj_i = env->boolean_ops[obj.id];
- BO_Impl obj2_i = env->boolean_ops[obj2.id];
- CT cutter = ev.cutter_api.distance_cut(obj_i.fd);
- CT cutter2 = ev.cutter_api.distance_cut(obj2_i.fd);
- P mesh = ev.polygon_api.intersect(ev, obj_i.mesh, obj2_i.mesh,
- obj_i.bools, obj2_i.bools,
- cutter, cutter2);
- O bools = ev.volume_api.min_op(obj_i.bools, obj2_i.bools);
- FD fd = ev.dist_api.max(obj_i.fd, obj2_i.fd);
- return create_bo(mesh, bools, fd);
- }
- class DistanceCut : public Cutter
- {
- public:
- DistanceCut(DistanceRenderable *dr) : dr(dr) {}
- std::vector<Point> cut(Point p1, Point p2) const
- {
- float d1 = dr->distance(p1);
- float d2 = dr->distance(p2);
- if (d1<d2)
- std::swap(p1,p2);
- Point p = p1;
- Vector v = (p2-p1);
- float dd = v.Dist();
- v /= dd;
- std::vector<Point> vec;
- //int count = 0;
- float pos = 0.0;
- while(1) {
- float d = dr->distance(p);
- //std::cout << "Dist: " << d << std::endl;
- //std::cout << "Pos: " << pos << std::endl;
- if (pos>1.0) { vec.push_back(p2); break; }//std::vector<Point>{ p2 };
- if (fabs(d)<0.0001) { vec.push_back(p); break; }
- //if (count>30) return Point(0.0,0.0,0.0);
- // p+=v * d;
- pos+=fabs(d/dd);
- //if (pos>=0.0 && pos<=1.0)
- p = (1.0-pos)*Vector(p1)+pos*Vector(p2);
- //count++;
- }
- //if (pos<0.0 ||pos>1.0)
- // std::cout << p1 << " " << p2 << ":" << p << std::endl;
- return vec;
- }
- private:
- DistanceRenderable *dr;
- };
- EXPORT GameApi::CT GameApi::CutterApi::distance_cut(FD dist1)
- {
- DistanceRenderable *dist = find_distance(e, dist1);
- return add_cutter(e, new DistanceCut(dist));
- }
- class CutFaces : public ForwardFaceCollection
- {
- public:
- CutFaces(FaceCollection *i, VolumeObject *oo, Cutter *cut) : ForwardFaceCollection(*i), i(i), oo(oo), cut(cut) { cut_them(); compress(); }
- void cut_them()
- {
- int f = i->NumFaces();
- for(int ii=0;ii<f; ii++)
- {
- faces.push_back(std::vector<Point>());
- int p = i->NumPoints(ii);
- //std::cout << p << std::endl;
- std::vector<Point> &ref = faces[faces.size()-1];
- //std::cout << "start" << std::endl;
- for(int jj=0;jj<p;jj++)
- {
- int jjj1 = jj;
- while(jjj1<0) jjj1+=p;
- while(jjj1>=p) jjj1-=p;
- int jjj2 = jjj1+1;
- while(jjj2<0) jjj2+=p;
- while(jjj2>=p) jjj2-=p;
- Point p1 = i->FacePoint(ii, jjj1);
- Point p2 = i->FacePoint(ii, jjj2);
- bool b1 = oo->Inside(p1);
- bool b2 = oo->Inside(p2);
- if (jj==0) { ref.push_back(p1); }
- if (!b1 && !b2) {
- //std::cout << "!b1 && !b2" << std::endl;
- //ref.push_back(p1);
- ref.push_back(p2);
- }
- if (!b1 && b2) {
- //std::cout << "!b1 && b2" << std::endl;
- Point prev = p1;
- Point curr = p2;
- for(int h=0;h<p;h++)
- {
- int jjj3 = jjj2+h;
- while(jjj3<0) jjj3+=p;
- while(jjj3>=p) jjj3-=p;
- curr = i->FacePoint(ii, jjj3);
- bool b3 = oo->Inside(curr);
- if (!b3) break;
- prev = curr;
- }
- std::vector<Point> c0 = cut->cut(p1,p2);
- std::vector<Point> c1 = cut->cut(prev,curr);
- //ref.push_back(p1);
- ref.push_back(c0[0]);
- ref.push_back(c1[0]);
- ref.push_back(curr);
- }
- #if 1
- if (b1 && !b2) {
- //std::cout << "b1 && !b2" << std::endl;
- std::vector<Point> c0 = cut->cut(p1,p2);
- //ref.push_back(c0[0]);
- ref.push_back(p2);
- }
- #endif
- //if (b1 && b2)
- // {
- // ref.push_back(p1);
- // ref.push_back(p2);
- // }
- }
- }
- }
- void compress()
- {
- int f = faces.size();
- int count = 0;
- for(int ii=0;ii<f; ii++)
- {
- int p = faces[ii].size();
- if (p==0 ||p==1 ||p==2) continue;
- faces2.push_back(std::vector<Point>());
- #if 1
- Point prev;
- for(int i=0;i<p;i++)
- {
- if ((prev-faces[ii][i]).Dist()>0.001)
- faces2[count].push_back(faces[ii][i]);
- prev = faces[ii][i];
- }
- #endif
- // faces2[count].push_back(faces2[count][0]);
- count++;
- }
- }
- virtual int NumFaces() const { return faces2.size(); }
- virtual int NumPoints(int face) const { return faces2[face].size(); }
- virtual Point FacePoint(int face, int point) const
- {
- return faces2[face][point];
- }
- virtual Vector PointNormal(int face, int point) const
- {
- Vector v(0.0, 0.0, 0.0);
- return v;
- }
- virtual float Attrib(int face, int point, int id) const { return 0.0; }
- virtual int AttribI(int face, int point, int id) const { return 0; }
- virtual unsigned int Color(int face, int point) const
- {
- return 0xffffffff;
- }
- virtual Point2d TexCoord(int face, int point) const
- {
- Point2d p;
- p.x = 0.0;
- p.y = 0.0;
- return p;
- }
- private:
- FaceCollection *i;
- VolumeObject *oo;
- Cutter *cut;
- std::vector<std::vector<Point> > faces;
- std::vector<std::vector<Point> > faces2;
- };
- EXPORT GameApi::P GameApi::PolygonApi::cut_faces(P p, O o, CT cutter)
- {
- FaceCollection *i = find_facecoll(e, p);
- VolumeObject *oo = find_volume(e, o);
- Cutter *cut = find_cutter(e, cutter);
- FaceCollection *coll = new CutFaces(i, oo, cut);
- return add_polygon(e, coll, 1);
- }
- EXPORT GameApi::P GameApi::PolygonApi::intersect(EveryApi &ev, P p1, P p2,
- O o1, O o2,
- CT cutter1, CT cutter2)
- {
- O o1_n = ev.volume_api.not_op(o1);
- O o2_n = ev.volume_api.not_op(o2);
- P p1_cut = cut_faces(p1, o2_n, cutter2);
- TS ts_1 = ev.ts_api.from_poly(p1_cut);
- P p_1 = ev.ts_api.to_poly(ts_1);
- P p2_cut = cut_faces(p2, o1_n, cutter1);
- TS ts_2 = ev.ts_api.from_poly(p2_cut);
- P p_2_ = ev.ts_api.to_poly(ts_2);
- P or_1 = or_elem(p_1, p_2_);
- return or_1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement