bool Sphere::IntersectBox( aabb& a_Box )
{
	float dmin = 0;
	vector3 v1 = a_Box.GetPos(), v2 = a_Box.GetPos() + a_Box.GetSize();
	if (m_Centre.x < v1.x) 
	{
		dmin = dmin + (m_Centre.x - v1.x) * (m_Centre.x - v1.x);
	}
	else if (m_Centre.x > v2.x)
	{
		dmin = dmin + (m_Centre.x - v2.x) * (m_Centre.x - v2.x);
	}
	if (m_Centre.y < v1.y)
	{
		dmin = dmin + (m_Centre.y - v1.y) * (m_Centre.y - v1.y);
	}
	else if (m_Centre.y > v2.y)
	{
		dmin = dmin + (m_Centre.y - v2.y) * (m_Centre.y - v2.y);
	}
	if (m_Centre.z < v1.z)
	{
		dmin = dmin + (m_Centre.z - v1.z) * (m_Centre.z - v1.z);
	}
	else if (m_Centre.z > v2.z)
	{
		dmin = dmin + (m_Centre.z - v2.z) * (m_Centre.z - v2.z);
	}
	return (dmin <= m_SqRadius);
}
예제 #2
0
float KDTree::caculateCost(SplitNode *split,aabb &frontBox, aabb &backBox)
{
	float frontArea = 2 * (frontBox.w()*frontBox.d() + frontBox.w()*frontBox.h() + frontBox.d()*frontBox.h());
	float backArea = 2 * (backBox.w()*backBox.d() + backBox.w()*backBox.h() +backBox.d()*backBox.h());

	return frontArea * split->nlcount+ backArea * split->nrcount;
}
예제 #3
0
void camera::view_all(aabb const& box, vec3 const& up)
{
    float diagonal = length(box.size());
    float r = diagonal * 0.5f;

    vec3 eye = box.center() + vec3(0, 0, r + r / std::atan(fovy_));

    look_at(eye, box.center(), up);
}
예제 #4
0
/* get cost of sah(surface area heuristic) method for certain plane */
double get_sah_cost(double plane, aabb &voxel, int num_left, int num_right) 
{
	aabb voxel_left, voxel_right;
	voxel.split_aabb(dim, plane, voxel_left, voxel_right);
	double sa_left = voxel_left.get_surface_area();
	double sa_right = voxel_right.get_surface_area();
	double sa_union = voxel.get_surface_area();

	return get_cost(sa_left / sa_union, sa_right / sa_union, num_left, num_right);
}
예제 #5
0
bool PlanePrim::IntersectBox( aabb& a_Box )
{
	vector3 v[2];
	v[0] = a_Box.GetPos(), v[1] = a_Box.GetPos() + a_Box.GetSize();
	int side1, side2 = 0, i = 0;
	for ( side1 = 0, side2 = 0, i = 0; i < 8; i++ )
	{
		vector3 p( v[i & 1].x, v[(i >> 1) & 1].y, v[(i >> 2) & 1].z );
		if ((DOT( p, m_Plane.N ) + m_Plane.D) < 0) side1++; else side2++;
	}
	if ((side1 == 0) || (side2 == 0)) return false; else return true;
}
예제 #6
0
파일: quadTree.hpp 프로젝트: makuto/horizon
 QuadTree(unsigned int newMaxCapacity, float newX, float newY, float newWidth, float newHeight)
 {
     depth = 1;
     //std::cout << "["<< depth <<"]node created\n";
     maxCapacity = newMaxCapacity;
     tL=NULL;
     tR=NULL;
     bL=NULL;
     bR=NULL;
     bounds.setPosition(newX, newY);
     bounds.resize(newWidth, newHeight);
 }
예제 #7
0
파일: sphere.cpp 프로젝트: nakdai/samples
bool sphere::bounding_box(float t0, float t1, aabb& _aabb)
{
    vec3 _min = center - vec3(radius, radius, radius);
    vec3 _max = center + vec3(radius, radius, radius);

    _aabb.init(_min, _max);

    return true;
}
예제 #8
0
파일: quadTree.hpp 프로젝트: makuto/horizon
 QuadTree(unsigned int newMaxCapacity, float newX, float newY, float newWidth, float newHeight, unsigned int newDepth)
 {
     depth = newDepth + 1;
     maxCapacity = newMaxCapacity;
     //Max depth reached; make sure this node holds a lot because
     //it won't subdivide any more
     if (depth >= MAX_TREE_DEPTH)
     {
         std::cout << "Max depth reached; setting capacity to MAX_DEPTH_CAPACITY\n";
         maxCapacity = MAX_DEPTH_CAPACITY;
     }
     tL=NULL;
     tR=NULL;
     bL=NULL;
     bR=NULL;
     bounds.setPosition(newX, newY);
     bounds.resize(newWidth, newHeight);
 }
예제 #9
0
파일: aap.cpp 프로젝트: yunteng/CubicaPlus
aap::aap(const aabb &total)
{
	VEC3F center = total.center();
	char xyz = 2;

	if (total.width() >= total.height() && total.width() >= total.depth()) {
		xyz = 0;
	} else
	if (total.height() >= total.width() && total.height() >= total.depth()) {
		xyz = 1;
	}

	this->xyz = xyz;
	this->p = center[xyz];
}
예제 #10
0
void Trigger::getLocalBounds( aabb& out ) const
{
	if ( triggerModel )
	{
		triggerModel->getBounds( out );
	}
	else
	{
		out.fromHalfSize( 4.f );
	}
}
예제 #11
0
bool IsAABBInsideSphere( const aabb& bb, const vec3_c& sphereCenter, float sphereRadius )
{
	float radSq = Square( sphereRadius );
	for ( u32 i = 0; i < 8; i++ )
	{
		vec3_c p = bb.getPoint( i );
		if ( p.distSQ( sphereCenter ) > radSq )
			return false;
	}
	return true;
}
예제 #12
0
파일: shapes.cpp 프로젝트: Zac-King/GameAI
const collision line_aabb(const line &a, const aabb &b)
{
	collision r;
	r.result = false;
	
	for (int i = 0; i < 4; ++i)
	{
		r.result = r.result || line_line(a, b.edge(i)).result;
	}

	return r;
}
예제 #13
0
void KDTree::GetBoxVertex(aabb box, Point3 *Pos)
{
	Point3 start;
	Point3 end;
	for(int i = 0; i< 3; i++)
	{
		start.cell[i] = box.GetPos().cell[i];
		end.cell[i] = box.GetPos().cell[i] + box.GetSize().cell[i];
	}

	Pos[0].set(start);
	Pos[6].set(end);

	Pos[1].set(Point3(end.x,start.y,start.z));
	Pos[2].set(Point3(end.x,start.y,end.z));
	Pos[3].set(Point3(start.x,start.y,end.z));

	Pos[4].set(Point3(start.x,end.y,start.z));
	Pos[5].set(Point3(end.x,end.y,start.z));
	Pos[7].set(Point3(start.x,end.y,end.z));
}
예제 #14
0
파일: shapes.cpp 프로젝트: Zac-King/GameAI
const collision aabb_aabb(const aabb &a, const aabb &b)
{
	collision r;
	debug("AABB AABB : only result, no normal data", false);

	r.result = 
	!(a.max().x < a.min().x ||
	b.max().x < a.min().x ||
	a.max().y < a.min().y ||
	b.max().y < a.min().y);

	return r;
}
예제 #15
0
void KDTree::Optimize(KDTreeNode* R,Side s,aabb AABB)
{
	if(!R) return;
	while(R->Type != LEFT)
	{
		if(s-2*R->m_Axis>=0&&s-2*R->m_Axis<=1)
		{
			if(s%2==0)
				R = R->m_rchild;
			else 
				R = R->m_lchild;

		}

		else if(R->m_Split >=AABB.GetPos().cell[R->m_Axis]+AABB.GetSize().cell[R->m_Axis])
			R = R->m_lchild;

		else if(R->m_Split <= AABB.GetPos().cell[R->m_Axis])
			R = R->m_rchild;

		else
			break;
	}
}
예제 #16
0
/* build kd-tree */
kdtree::kdtree(aabb &voxel, vector<primitive*> &pris, int depth, kdtree* parent)
{
	parent_kdtree = parent;
	left_kdtree = right_kdtree = NULL;
	bbox = voxel;

	/* end criteria; make this leaf */
	if (depth > maximum_depth || pris.size() < 1)
	{
		primitives = pris;
	}

	/* general case: determine whether and how to devide current voxel */
	else
	{
		double cost_asleaf = cost_i * pris.size();	
		cost_min = 1E100;							

		for (dim = 0; dim < 3; dim++)
		{
			get_best_plane(pris, voxel);
		}

		/* internal node; divide further */
		if (cost_min < cost_asleaf)
		{
			vector<primitive*> left_pris, right_pris;
			classify_primitives(pris, best_plane, left_pris, right_pris);

			aabb left_voxel, right_voxel;
			voxel.split_aabb(best_dim, best_plane, left_voxel, right_voxel);

			left_kdtree = new kdtree(left_voxel, left_pris, depth + 1, this);
			right_kdtree = new kdtree(right_voxel, right_pris, depth + 1, this);
		}

		/* leaf; division end */
		else							
		{
			primitives = pris;
		}
	}
}
예제 #17
0
파일: vvibr.cpp 프로젝트: aumuell/deskvox
void calcDepthRange(mat4 const& pr, mat4 const& mv,
                    aabb const& bbox, float& minval, float& maxval)
{
    vec3 center = vec4( mv * vec4(bbox.center(), 1.0f) ).xyz();
    vec3 min    = vec4( mv * vec4(bbox.min, 1.0f) ).xyz();
    vec3 max    = vec4( mv * vec4(bbox.max, 1.0f) ).xyz();

    float radius = length(max - min) * 0.5f;

    // Depth buffer of ibrPlanes
    vec3 scal(center);
    scal = normalize(scal) * radius;
    min = center - scal;
    max = center + scal;

    vec4 min4 = pr * vec4(min, 1.f);
    vec4 max4 = pr * vec4(max, 1.f);

    min = min4.xyz() / min4.w;
    max = max4.xyz() / max4.w;

    minval = (min.z+1.f) * 0.5f;
    maxval = (max.z+1.f) * 0.5f;
}
예제 #18
0
파일: shapes.cpp 프로젝트: Zac-King/GameAI
void draw_aabb(const mat4 &m, const aabb &a, const vec4 &color)
{
	for (int i = 0; i < 4; ++i)
		draw_line(m, a.edge(i), color);
}
예제 #19
0
파일: frustum.cpp 프로젝트: YoutaVen/Vulkan
VkBool32 frustum::isVisible(const aabb& aabbWorld) const
{
	return isVisible(aabbWorld.getObb());
}
예제 #20
0
bool KDTree::findOptimalSplitPositon(TriangleList *list,aabb &box,int depth, real &splitPosition,aabb &frontBox, aabb &backBox)
{
	bool foundOptimalSplit = false;

	//make a list of the split position candidates
	int axis = depth % Dimension;    
	real pos1 = box.GetPos().cell[axis];//the rangle of the axis direction within the box
	real pos2 = box.GetPos().cell[axis] + box.GetSize().cell[axis];

	bool *pright = new bool[list->GetCount()];
	TriangleNode *tempList = list->GetHead();
	SplitList* SList = new SplitList();
	int aidx = 0;
	while(tempList)
	{
		real pos;
		pright[aidx++]= true;
		for(int i=0;i<3;i++)
		{
			pos = tempList->GetVertex(i).cell[axis];
			if((pos >= pos1)&&(pos <= pos2)) SList->InsertSplitPos(pos);
		}
		tempList = tempList->GetNext();
	}

	//determine nlcount / nrcont for each split position
	aabb tempFrontBox = box;
	aabb tempBackBox = box;
	float tempFrontBoxp1 = tempFrontBox.GetPos().cell[axis];
	float tempBackBoxp2 = tempBackBox.GetPos().cell[axis] + tempBackBox.GetSize().cell[axis];
	SplitNode* splist = SList->GetHead();
	while(splist!=NULL)
	{
		tempBackBox.GetPos().cell[axis] = splist->splitpos;
		tempBackBox.GetSize().cell[axis] = pos2 - splist->splitpos;
		tempFrontBox.GetSize().cell[axis] = splist->splitpos - pos1;

		float tempFrontBoxp2 = tempFrontBox.GetPos().cell[axis] + tempFrontBox.GetSize().cell[axis];
		float tempBackBoxp1 = tempBackBox.GetPos().cell[axis];
		tempList = list->GetHead();
		int i = 0;
		while(tempList)
		{
			if(pright[i])
			{
				int position = partitionTriangle(tempList,depth,splist->splitpos);
				switch(position)
				{
				case kdBefore:
					splist->nlcount++;
					pright[i]=false;
					break;
				case kdAfter:
					splist->nrcount++;
					break;
				case kdIntersection:
					splist->nlcount++;
					splist->nrcount++;
					break;
				}
			}else
			{
				splist->nlcount++;
			}
			tempList = tempList->GetNext();
		}
		splist = splist->next;
		i++;
	}
	delete pright;

	float bestPos = 0.0;
	float lowCost = caculateSingleVoxelCost(list->GetCount(),box);
	float bestCost = lowCost;
	splist = SList->GetHead();
	while(splist)
	{
		tempBackBox.GetPos().cell[axis] = splist->splitpos;
		tempBackBox.GetSize().cell[axis] = pos2 - splist->splitpos;
		tempFrontBox.GetSize().cell[axis] = splist->splitpos - pos1;

		real splitcost = cTraversal * lowCost + caculateCost(splist,tempFrontBox,tempBackBox);
		if(splitcost < lowCost)
		{
			foundOptimalSplit = true;
			bestCost = splitcost;
			bestPos = splist->splitpos;
			frontBox = tempFrontBox;
			backBox = tempBackBox;
			
		}
		splist = splist->next;
	}
	splitPosition = bestPos;
	return foundOptimalSplit;
}
예제 #21
0
float KDTree::caculateSingleVoxelCost(int numofTriangles,aabb &box)
{
	float area = 2 * (box.w()*box.d() + box.w()*box.h() + box.d()*box.h());
	return area * numofTriangles;
}
예제 #22
0
파일: kd_tree.cpp 프로젝트: proton/ireon
void ireon::kd_tree::KdTree<T>::subdivide( KdTreeNode<T>* node, const aabb& box, int depth, int a_Prims )
{
	// recycle used split list nodes
	//add sPool_ at end sList_
	if (sList_)
	{
		SplitList* list = sList_;
		while (list->next) 
			list = list->next;
		list->next = sPool_;
		sPool_ = sList_, sList_ = 0;
	}

	// determine split axis
	Vector3 s = box.getSize();
	if ((s.x >= s.y) && (s.x >= s.z)) 
		node->setAxis( 0 );
	else if ((s.y >= s.x) && (s.y >= s.z))
		node->setAxis( 1 );
	
	int axis = node->getAxis();
	
	// make a list of the split position candidates
	ObjectList<T>* l = node->getList();
	real p1, p2;
	real pos1 = box.getPos().val[axis];
	real pos2 = box.getPos().val[axis] + box.getSize().val[axis];
	bool* pright = new bool[a_Prims];
	float* eleft = new float[a_Prims], *eright = new float[a_Prims];
	T** parray = new T*[a_Prims];
	
	real etleft, etright;
	int aidx = 0;
	while (l)
	{
		T* p = parray[aidx] = l->getPrimitive();
		pright[aidx] = true;

		etleft =  eleft[aidx];
		etright = eright[aidx];
		p->calculateRange( etleft, etright, axis );
		eleft[aidx] = (float)etleft;
		eright[aidx] = (float)etright;
		aidx++;
		for ( int i = 0; i < 3; i++ )
		{
			p1 = (float)p->vertice( i )->cell[axis];
			if ((p1 >= pos1) && (p1 <= pos2)) 
				insertSplitPos( p1 );
		}
		
		l = l->getNext();
	}
	// determine n1count / n2count for each split position
	aabb b1, b2, b3 = box, b4 = box;
	SplitList* splist = sList_;
	float b3p1 = b3.getPos().val[axis];
	float b4p2 = b4.getPos().val[axis] + b4.getSize().val[axis];
	Vector3 foo;
	while (splist)
	{
		foo = b4.getPos();
		foo.val[axis] = splist->splitpos;
		b4.setPos(foo);
		foo = b4.getSize();
		foo.val[axis] = pos2 - splist->splitpos;
		b4.setSize(foo);
		foo = b3.getSize();
		foo.val[axis] = splist->splitpos - pos1;
		b3.setSize(foo);
		
		float b3p2 = b3.getPos().val[axis] + b3.getSize().val[axis];
		float b4p1 = b4.getPos().val[axis];
		for ( int i = 0; i < a_Prims; i++ ) if (pright[i])
		{
			T* p = parray[i];
			if ((eleft[i] <= b3p2) && (eright[i] >= b3p1))
				if (p->intersectBox( b3 )) splist->n1count++;
			if ((eleft[i] <= b4p2) && (eright[i] >= b4p1))
				if (p->intersectBox( b4 )) splist->n2count++; else pright[i] = false;
		}
		else splist->n1count++;
		splist = splist->next;
	}
	delete[] pright;
	// calculate surface area for current node
	real SAV = 0.5f / (box.w() * box.d() + box.w() * box.h() + box.d() * box.h());
	// calculate cost for not splitting
	real Cleaf = a_Prims * 1.0f;
	// determine optimal split plane position
	splist = sList_;
	real lowcost = 10000;
	real bestpos = 0;
	while (splist)
	{
		// calculate child node extends
		foo = b4.getPos();
		foo.val[axis] = splist->splitpos;
		b4.setPos(foo);
		foo = b4.getSize();
		foo.val[axis] = pos2 - splist->splitpos;
		b4.setSize(foo);
		foo = b3.getSize();
		foo.val[axis] = splist->splitpos - pos1;
		b3.setSize(foo);

		// calculate child node cost
		real SA1 = 2 * (b3.w() * b3.d() + b3.w() * b3.h() + b3.d() * b3.h());
		real SA2 = 2 * (b4.w() * b4.d() + b4.w() * b4.h() + b4.d() * b4.h());
		real splitcost = 0.3f + 1.0f * (SA1 * SAV * splist->n1count + SA2 * SAV * splist->n2count);
		// update best cost tracking variables
		if (splitcost < lowcost)
		{
			lowcost = splitcost;
			bestpos = splist->splitpos;
			b1 = b3, b2 = b4;
		}
		splist = splist->next;
	}
	if (lowcost > Cleaf) 
	{
		delete[] eleft;
		delete[] eright;
		delete[] parray;
		return;
	}
		node->setSplitPos( bestpos );
	// construct child nodes
	KdTreeNode<T>* left = s_MManager->NewKdTreeNodePair();
	int n1count = 0, n2count = 0, total = 0;
	// assign primitives to both sides
	float b1p1 = b1.getPos().val[axis];
	float b2p2 = b2.getPos().val[axis] + b2.getSize().val[axis];
	float b1p2 = b1.getPos().val[axis] + b1.getSize().val[axis];
	float b2p1 = b2.getPos().val[axis];
	for ( int i = 0; i < a_Prims; i++ )
	{
		T* p = parray[i];
		total++;
		if ((eleft[i] <= b1p2) && (eright[i] >= b1p1)) if (p->intersectBox( b1 )) 
		{
			left->add( p );
			n1count++;
		}
		if ((eleft[i] <= b2p2) && (eright[i] >= b2p1)) if (p->intersectBox( b2 )) 
		{
			(left + 1)->add( p );
			n2count++;
		}
	}
	delete[] eleft;
	delete[] eright;
	delete[] parray;
	
	s_MManager->FreeObjectList( node->getList() );
	
	node->setLeft( left );
	node->setLeaf( false );
	if (depth < MAXTREEDEPTH)
	{
		if (n1count > 2) subdivide( left, b1, depth + 1, n1count );
		if (n2count > 2) subdivide( left + 1, b2, depth + 1, n2count );
	}
}
예제 #23
0
파일: ogl-pool.cpp 프로젝트: rlk/thumb
void ogl::unit::merge_bound(aabb& b) const
{
    // Merge the local mesh bounding volume with the given one.

    if (active) b.merge(my_aabb);
}