Пример #1
0
int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) {

	if (p_depth > max_depth) {
		max_depth = p_depth;
	}

	if (p_size == 1) {

		return p_bb[p_from] - p_bvh;
	} else if (p_size == 0) {

		return -1;
	}

	AABB aabb;
	aabb = p_bb[p_from]->aabb;
	for (int i = 1; i < p_size; i++) {

		aabb.merge_with(p_bb[p_from + i]->aabb);
	}

	int li = aabb.get_longest_axis_index();

	switch (li) {

		case Vector3::AXIS_X: {
			SortArray<BVH *, BVHCmpX> sort_x;
			sort_x.nth_element(0, p_size, p_size / 2, &p_bb[p_from]);
			//sort_x.sort(&p_bb[p_from],p_size);
		} break;
		case Vector3::AXIS_Y: {
			SortArray<BVH *, BVHCmpY> sort_y;
			sort_y.nth_element(0, p_size, p_size / 2, &p_bb[p_from]);
			//sort_y.sort(&p_bb[p_from],p_size);
		} break;
		case Vector3::AXIS_Z: {
			SortArray<BVH *, BVHCmpZ> sort_z;
			sort_z.nth_element(0, p_size, p_size / 2, &p_bb[p_from]);
			//sort_z.sort(&p_bb[p_from],p_size);

		} break;
	}

	int left = _create_bvh(p_bvh, p_bb, p_from, p_size / 2, p_depth + 1, max_depth, max_alloc);
	int right = _create_bvh(p_bvh, p_bb, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, max_depth, max_alloc);

	int index = max_alloc++;
	BVH *_new = &p_bvh[index];
	_new->aabb = aabb;
	_new->center = aabb.position + aabb.size * 0.5;
	_new->face_index = -1;
	_new->left = left;
	_new->right = right;

	return index;
}
Пример #2
0
void TriangleMesh::create(const DVector<Vector3>& p_faces) {

	valid=false;

	int fc=p_faces.size();
	ERR_FAIL_COND(!fc || ((fc%3) != 0));
	fc/=3;
	triangles.resize(fc);

	bvh.resize(fc*3); //will never be larger than this (todo make better)
	DVector<BVH>::Write bw = bvh.write();

	{

		//create faces and indices and base bvh
		//except for the Set for repeated triangles, everything
		//goes in-place.

		DVector<Vector3>::Read r = p_faces.read();
		DVector<Triangle>::Write w = triangles.write();
		Map<Vector3,int> db;

		for(int i=0;i<fc;i++) {

			Triangle&f=w[i];
			const Vector3 *v=&r[i*3];

			for(int j=0;j<3;j++) {

				int vidx=-1;
				Vector3 vs=v[j].snapped(0.0001);
				Map<Vector3,int>::Element *E=db.find(vs);
				if (E) {
					vidx=E->get();
				} else {
					vidx=db.size();
					db[vs]=vidx;
				}

				f.indices[j]=vidx;
				if (j==0)
					bw[i].aabb.pos=vs;
				else
					bw[i].aabb.expand_to(vs);
			}

			f.normal=Face3(r[i*3+0],r[i*3+1],r[i*3+2]).get_plane().get_normal();

			bw[i].left=-1;
			bw[i].right=-1;
			bw[i].face_index=i;
			bw[i].center=bw[i].aabb.pos+bw[i].aabb.size*0.5;
		}

		vertices.resize(db.size());
		DVector<Vector3>::Write vw = vertices.write();
		for (Map<Vector3,int>::Element *E=db.front();E;E=E->next()) {
			vw[E->get()]=E->key();
		}

	}

	DVector<BVH*> bwptrs;
	bwptrs.resize(fc);
	DVector<BVH*>::Write bwp = bwptrs.write();
	for(int i=0;i<fc;i++) {

		bwp[i]=&bw[i];
	}

	max_depth=0;
	int max_alloc=fc;
	int max=_create_bvh(bw.ptr(),bwp.ptr(),0,fc,1,max_depth,max_alloc);

	bw=DVector<BVH>::Write(); //clearup
	bvh.resize(max_alloc); //resize back

	valid=true;

}