void test(const shared_ptr< DistanceOctree< MeshType > > & distanceOctree, const MeshType & mesh, const AABB & domainAABB, Vector3<uint_t> numBlocks)
{
   Vector3<real_t> blockSize(domainAABB.xSize() / real_c(numBlocks[0]),
      domainAABB.ySize() / real_c(numBlocks[1]),
      domainAABB.zSize() / real_c(numBlocks[2]));

   real_t maxError = blockSize.min() / real_t(10);

   SetupBlockForest setupBlockforest;
   setupBlockforest.addRootBlockExclusionFunction(F(distanceOctree, maxError));
   setupBlockforest.addWorkloadMemorySUIDAssignmentFunction(blockforest::uniformWorkloadAndMemoryAssignment);


   setupBlockforest.init(domainAABB, numBlocks[0], numBlocks[1], numBlocks[2], false, false, false);
   WALBERLA_LOG_DEVEL(setupBlockforest.toString());


   std::vector< Vector3<real_t> > vertexPositions;
   vertexPositions.reserve(mesh.n_vertices());
   for (auto vIt = mesh.vertices_begin(); vIt != mesh.vertices_end(); ++vIt)
   {
      vertexPositions.push_back(toWalberla(mesh.point(*vIt)));
   }

   std::vector< const blockforest::SetupBlock* > setupBlocks;
   setupBlockforest.getBlocks(setupBlocks);

   // Check wether all vertices are located in allocated blocks
   std::vector< Vector3<real_t> > uncoveredVertices(vertexPositions);

   for (auto bIt = setupBlocks.begin(); bIt != setupBlocks.end(); ++bIt)
   {
      const AABB & aabb = (*bIt)->getAABB();

      uncoveredVertices.erase(std::remove_if(uncoveredVertices.begin(), uncoveredVertices.end(), PointInAABB(aabb)), uncoveredVertices.end());
   }

   WALBERLA_CHECK(uncoveredVertices.empty(), "Not all vertices of the mesh are located in allocated blocks!");

   //setupBlockforest.assignAllBlocksToRootProcess();
   //setupBlockforest.writeVTKOutput( "setupblockforest" );
}
Beispiel #2
0
/// [groupSyntax]
bool Triangle::Intersects(const AABB &aabb) const
{
/** The AABB-Triangle test implementation is based on the pseudo-code in
	Christer Ericson's Real-Time Collision Detection, pp. 169-172. */
	///@todo The Triangle-AABB intersection test can be greatly optimized by manually unrolling loops, trivial math and by avoiding
	/// unnecessary copying.
	float t1, t2, a1, a2;
	const float3 e[3] = { float3(1,0,0), float3(0,1,0), float3(0,0,1) };

	for(int i = 0; i < 3; ++i)
	{
		ProjectToAxis(e[i], t1, t2);
		aabb.ProjectToAxis(e[i], a1, a2);
		if (!RangesOverlap(t1, t2, a1, a2))
			return false;
	}

	float3 n = UnnormalizedNormalCCW();
	ProjectToAxis(n, t1, t2);
	aabb.ProjectToAxis(n, a1, a2);
	if (!RangesOverlap(t1, t2, a1, a2))
		return false;

	const float3 t[3] = { b-a, c-a, c-b };

	for(int i = 0; i < 3; ++i)
		for(int j = 0; j < 3; ++j)
		{
			float3 axis = Cross(e[i], t[j]);
			float len = axis.LengthSq();
			if (len <= 1e-4f)
				continue; // Ignore tests on degenerate axes.

			ProjectToAxis(axis, t1, t2);
			aabb.ProjectToAxis(axis, a1, a2);
			if (!RangesOverlap(t1, t2, a1, a2))
				return false;
		}

	// No separating axis exists, the AABB and triangle intersect.
	return true;
}
	void LightFieldCube::read(File *file, size_t head_address, AABB aabb) {
		file->readInt32BE(&type);
		file->readInt32BE(&value);

		point = aabb.center();

		if (type != LIBGENS_LIGHTFIELD_CUBE_NO_SPLIT) {
			left = new LightFieldCube();
			right = new LightFieldCube();

			file->goToAddress(head_address + LIBGENS_LIGHTFIELD_CUBE_SIZE * value);
			left->read(file, head_address, aabb.half(type, LIBGENS_MATH_SIDE_LEFT));

			file->goToAddress(head_address + LIBGENS_LIGHTFIELD_CUBE_SIZE * (value+1));
			right->read(file, head_address, aabb.half(type, LIBGENS_MATH_SIDE_RIGHT));
		}
		else {

		}
	}
Beispiel #4
0
_Use_decl_annotations_
void BIH::Query(const AABB& test, uint32_t* numTriangles)
{
    *numTriangles = 0;
    if (!test.Intersects(_bounds))
    {
        return;
    }

    Query(test, _root, numTriangles);
}
Beispiel #5
0
int BroadPhaseBasic::cull_segment(const Vector3& p_from, const Vector3& p_to,CollisionObjectSW** p_results,int p_max_results,int *p_result_indices) {

	int rc=0;

	for (Map<ID,Element>::Element *E=element_map.front();E;E=E->next()) {

		const AABB aabb=E->get().aabb;
		if (aabb.intersects_segment(p_from,p_to)) {

			p_results[rc]=E->get().owner;
			p_result_indices[rc]=E->get().subindex;
			rc++;
			if (rc>=p_max_results)
				break;
		}
	}

	return rc;

}
Beispiel #6
0
	AABB MOFMesh::getBoudingBox()
	{
		AABB aabb;
		Vector3D min;
		Vector3D max;

		if(this->m_numMeshes>0)
			aabb = this->getSubmesh(0)->getBoudingBox();

		for(int i=0; i<this->m_numMeshes; ++i)
		{
			MOFSubmesh *smesh;
			smesh = this->getSubmesh(i);

			AABB sAABB = smesh->getBoudingBox();
			aabb.load(sAABB);
		}

		return aabb;
	}
Beispiel #7
0
 bool cull(const AABB& aabb) const
 {
   if (aabb.isNull())
     return false;
   for(unsigned i=0; i<planes().size(); ++i)
   {
     if ( plane(i).isOutside(aabb) )
       return true;
   }
   return false;
 }
Beispiel #8
0
AABB AABB::GetTransformedAABB(const Matrix4x4f &mat) const
{
	AABB transformedAABB;

	Vec3f newCenter(mat * m_center);

	transformedAABB.m_lowerBound = newCenter;
	transformedAABB.m_upperBound = newCenter;

	// Loop through all corners, transform, and compare
	for(int x = -1; x <= 1; x += 2)
		for(int y = -1; y <= 1; y += 2)
			for(int z = -1; z <= 1; z += 2)
			{
				Vec3f corner(x * m_halfDims.x + m_center.x, y * m_halfDims.y + m_center.y, z * m_halfDims.z + m_center.z);

				// Transform the corner
				corner = mat * corner;

				// Compare bounds
				if(corner.x > transformedAABB.m_upperBound.x)
					transformedAABB.m_upperBound.x = corner.x;
				if(corner.y > transformedAABB.m_upperBound.y)
					transformedAABB.m_upperBound.y = corner.y;
				if(corner.z > transformedAABB.m_upperBound.z)
					transformedAABB.m_upperBound.z = corner.z;

				if(corner.x < transformedAABB.m_lowerBound.x)
					transformedAABB.m_lowerBound.x = corner.x;
				if(corner.y < transformedAABB.m_lowerBound.y)
					transformedAABB.m_lowerBound.y = corner.y;
				if(corner.z < transformedAABB.m_lowerBound.z)
					transformedAABB.m_lowerBound.z = corner.z;
			}

	// Move from local into world space
	transformedAABB.CalculateHalfDims();
	transformedAABB.CalculateCenter();

	return transformedAABB;
}
Beispiel #9
0
/// NOTE: Expects @param nodes to be a link list along the left child
AABB::AABB(AABB *nodes) : left(0), right(0), move(0) {
  if (!nodes) return;

  // Compute bounds
  unsigned count = 0;
  for (AABB *it = nodes; it; it = it->left) {
    if (it->right) THROW("Unexpected right-hand AABB node");
    add(*it);
    count++;
  }

  // Degenerate cases
  if (count < 3) {
    if (count == 2) right = nodes->left;
    left = nodes->prepend(0);
    return;
  }

  // Decide split
  unsigned axis = getDimensions().findLargest();
  real cut = getMax()[axis] + getMin()[axis];

  // Partition nodes
  AABB *lessThan = 0;
  AABB *greaterThan = 0;
  unsigned lessCount = 0;
  unsigned greaterCount = 0;

  for (AABB *it = nodes; it;) {
    AABB *next = it->left;
    bool less = it->getMax()[axis] + it->getMin()[axis] < cut;

    if (less) {lessThan = it->prepend(lessThan); lessCount++;}
    else {greaterThan = it->prepend(greaterThan); greaterCount++;}

    it = next;
  }

  // Check for bad partition
  if (!lessThan) lessThan = greaterThan->split(greaterCount / 2);
  if (!greaterThan) greaterThan = lessThan->split(lessCount / 2);

  // Recur
  left = new AABB(lessThan);
  right = new AABB(greaterThan);
}
Beispiel #10
0
void Mesh::add_surface(PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes,bool p_alphasort) {


	ERR_FAIL_COND(p_arrays.size()!=ARRAY_MAX);

	Surface s;

	VisualServer::get_singleton()->mesh_add_surface(mesh,(VisualServer::PrimitiveType)p_primitive, p_arrays,p_blend_shapes,p_alphasort);
	surfaces.push_back(s);



	/* make aABB? */ {

		DVector<Vector3> vertices=p_arrays[ARRAY_VERTEX];
		int len=vertices.size();
		ERR_FAIL_COND(len==0);
		DVector<Vector3>::Read r=vertices.read();
		const Vector3 *vtx=r.ptr();

		// check AABB
		AABB aabb;
		for (int i=0;i<len;i++) {

			if (i==0)
				aabb.pos=vtx[i];
			else
				aabb.expand_to(vtx[i]);
		}

		surfaces[surfaces.size()-1].aabb=aabb;
		surfaces[surfaces.size()-1].alphasort=p_alphasort;

		_recompute_aabb();

	}

	triangle_mesh=Ref<TriangleMesh>();
	_change_notify();

}
/**
* @return The axis-aligned bounding box (AABB) of the body in world-space coordinates
*/
AABB CollisionBody::getAABB() const {

    AABB bodyAABB;

    if (mProxyCollisionShapes == NULL) return bodyAABB;

    mProxyCollisionShapes->getCollisionShape()->computeAABB(bodyAABB, mTransform * mProxyCollisionShapes->getLocalToBodyTransform());

    // For each proxy shape of the body
    for (ProxyShape* shape = mProxyCollisionShapes->mNext; shape != NULL; shape = shape->mNext) {

        // Compute the world-space AABB of the collision shape
        AABB aabb;
        shape->getCollisionShape()->computeAABB(aabb, mTransform * shape->getLocalToBodyTransform());

        // Merge the proxy shape AABB with the current body AABB
        bodyAABB.mergeWithAABB(aabb);
    }

    return bodyAABB;
}
Beispiel #12
0
bool World::overlapsCollidableTiles(int centerX, int centerY, int nodeWidth, int nodeHeight)
{
	vector<WorldLayer*>::iterator it = layers->begin();
	while (it != layers->end())
	{
		WorldLayer *layer = (*it);
		if (layer->hasCollidableTiles())
		{
			AABB aabb;
			aabb.setCenterX((float)centerX);
			aabb.setCenterY((float)centerY);
			aabb.setWidth((float)nodeWidth);
			aabb.setHeight((float)nodeHeight);
			bool overlaps = layer->overlapsCollidableTile(aabb);
			if (overlaps)
				return true;
		}
		it++;
	}
	return false;
}
Beispiel #13
0
bool CScene::CollisionCheck( CGameObject *pObj1, CGameObject *pObj2 )
{
	// 충돌되면 true 반환
	AABB playerBox = pObj1->m_bcMeshBoundingCube;
	AABB objBox = pObj2->m_bcMeshBoundingCube;

	// AABB를 해당 오브젝트에 맞게 변환		-> 물체를 생성할 때 위치를 잡고나면 update하지 않아도 되야 하는데 자꾸 초기화됨
	playerBox.Update( &( pObj1->m_mtxWorld ) );
	objBox.Update( &( pObj2->m_mtxWorld ) );

	// AABB 출돌 검사
	if (playerBox.m_vMax.x < objBox.m_vMin.x) return true;
	if (playerBox.m_vMax.y < objBox.m_vMin.y) return true;
	if (playerBox.m_vMax.z < objBox.m_vMin.z) return true;
	if (playerBox.m_vMin.x > objBox.m_vMax.x) return true;
	if (playerBox.m_vMin.y > objBox.m_vMax.y) return true;
	if (playerBox.m_vMin.z > objBox.m_vMax.z) return true;

	// 아무런 체크도 되지 않으면 충돌하지 않은 것
	return false;
}
Beispiel #14
0
pair<double, SplitSide> SAH(SplitPlane plane, AABB box, int left, int right, int planar) {
	pair<AABB, AABB> boxes = box.split(plane);
	double area = surfaceArea(box);
	double ratioLeft = surfaceArea(boxes.first) / area;
	double ratioRight = surfaceArea(boxes.second) / area;

	double costLeft = cost(ratioLeft, ratioRight, left + planar, right);
	double costRight = cost(ratioLeft, ratioRight, left, planar + right);

	if (costLeft < costRight) return make_pair(costLeft, LEFT);
	else return make_pair(costRight, RIGHT);
}
/// Determines whether a point is outside of a AABB
bool AABB::outside(const AABB& a, const Point3d& point, double tol)
{
  const unsigned THREE_D = 3;

  assert(a.get_relative_pose() == point.pose);

  for (unsigned i=0; i< THREE_D; i++)
    if (point[i] < a.minp[i] - tol || point[i] > a.maxp[i] + tol)
      return true;

  return false;
}
Beispiel #16
0
AABB AnimatedTransform::getSpatialBounds(const AABB &aabb) const {
	AABB result;

	if (m_tracks.size() == 0) {
		for (int j=0; j<8; ++j)
			result.expandBy(m_transform(aabb.getCorner(j)));
	} else {
		/* Compute approximate bounds */
		int nSteps = 100;
		AABB1 timeBounds = getTimeBounds();
		Float step = timeBounds.getExtents().x / (nSteps-1);

		for (int i=0; i<nSteps; ++i) {
			const Transform &trafo = eval(timeBounds.min.x + step * i);
			for (int j=0; j<8; ++j)
				result.expandBy(trafo(aabb.getCorner(j)));
		}
	}

	return result;
}
void PUBaseCollider::populateAlignedBox( AABB& box, const Vec3& position, const float width, const float height, const float depth )
{
    float halfWidth = 0.5f * width;
    float halfHeight = 0.5f * height;
    float halfDepth = 0.5f * depth;
    box.set(Vec3(position.x - halfWidth, 
        position.y - halfHeight, 
        position.z - halfDepth),
        Vec3(position.x + halfWidth, 
        position.y + halfHeight, 
        position.z + halfDepth));
}
Beispiel #18
0
AABB Mesh::generateBoundingAABB() const
{
  AABB bounds;

  if (vertices.empty())
    return bounds;

  vec3 minimum(std::numeric_limits<float>::max());
  vec3 maximum(std::numeric_limits<float>::min());

  for (auto& v : vertices)
  {
    minimum = min(minimum, v.position);
    maximum = max(maximum, v.position);
  }

  bounds.setBounds(minimum.x, minimum.y, minimum.z,
                   maximum.x, maximum.y, maximum.z);

  return bounds;
}
Beispiel #19
0
//=============================================================================
// AABB同士の当たり判定
//=============================================================================
bool CCollisionManager::JudgeAABBCross(
	const VECTOR3& p1, const AABB& b1,
	const VECTOR3& p2, const AABB& b2)
{
	VECTOR3 min_pos1;
	VECTOR3 min_pos2;
	min_pos1._x = p1._x + b1.Min._x;
	min_pos1._y = p1._y + b1.Min._y;
	min_pos1._z = p1._z + b1.Min._z;
	min_pos2._x = p2._x + b2.Min._x;
	min_pos2._y = p2._y + b2.Min._y;
	min_pos2._z = p2._z + b2.Min._z;

	bool bHitX = 
		min_pos1._x <= min_pos2._x + b2.width() &&
		min_pos1._x >= min_pos2._x - b1.width();
	bool bHitY =
		min_pos1._y <= min_pos2._y + b2.height() &&
		min_pos1._y >= min_pos2._y - b1.height();
	bool bHitZ =
		min_pos1._z <= min_pos2._z + b2.depth() &&
		min_pos1._z >= min_pos2._z - b1.depth();

	if(!bHitX || !bHitY || !bHitZ)
	{
		return false;
	}

	return true;
}
Beispiel #20
0
bool AABB::CheckCollision(AABB otherBox)
{
    //
	//     b0--------b1
	//      |        |
	// a0---|----a1  |
	//  |   |    |   |
	//  |  b3--------b2
	//  |        |
	//  |        |
	// a3--------a2
    //
	// (a0.x is less than b1.x and a1.x is greater than b0.x) collided in x axis
	// (a0.y is less than b3.y and a3.y is greater than b0.y) collided in y axis
	//
	if ((_x < otherBox.GetX() + otherBox.GetWidth() &&  _x + _width > otherBox.GetX()) &&
		(_y < otherBox.GetY() + otherBox.GetHeight() && _y + _height > otherBox.GetY()))
	{
		// we collided
		return true;
	}
	else
	{
		return false;
	}
}
Beispiel #21
0
bool Ray::intersectAABB(const AABB &aabb) const {
	Vector3d dirFrac;
	dirFrac.x() = 1.0f / _direction.x();
	dirFrac.y() = 1.0f / _direction.y();
	dirFrac.z() = 1.0f / _direction.z();

	float t1 = (aabb.getMin().x() - _origin.x()) * dirFrac.x();
	float t2 = (aabb.getMax().x() - _origin.x()) * dirFrac.x();
	float t3 = (aabb.getMin().y() - _origin.y()) * dirFrac.y();
	float t4 = (aabb.getMax().y() - _origin.y()) * dirFrac.y();
	float t5 = (aabb.getMin().z() - _origin.z()) * dirFrac.z();
	float t6 = (aabb.getMax().z() - _origin.z()) * dirFrac.z();

	float tMin = MAX(MAX(MIN(t1, t2), MIN(t3, t4)), MIN(t5, t6));
	float tMax = MIN(MIN(MAX(t1, t2), MAX(t3, t4)), MAX(t5, t6));

	// If tMax < 0, the ray is intersecting the AABB, but the whole AABB is in the opposite direction
	if (tMax < 0) {
		return false;
	}

	// If tMin > tMax, the ray doesn't intersect the AABB
	if (tMin > tMax) {
		return false;
	}

	return true;
}
bool VolMeshIO::fitmesh(VolMesh* vm, const AABB& toBox) {
	if(!toBox.isValid())
		return false;

	AABB curBox = vm->computeAABB();

	vec3f s = vec3f::div(toBox.extent(), curBox.extent());
	double minScaleFactor = MATHMIN(MATHMIN(s.x, s.y), s.z);
	vec3d scale(minScaleFactor);

	vec3f t = toBox.lower() - curBox.lower();
	vec3d translate(t.x, t.y, t.z);


	//first translate all nodes
	for(U32 i=0; i < vm->countNodes(); i++) {
		NODE& p = vm->nodeAt(i);

		//translate
		p.pos = p.pos + translate;
		p.restpos = p.restpos + translate;

		//scale
		p.pos = p.pos * minScaleFactor;
		p.restpos = p.restpos * minScaleFactor;
	}

	return true;
}
Beispiel #23
0
CollisionData iTest(const AABB & rect, const Circle & circle)
{
	CollisionData cd = { false, 0, 0, 0 };
	cd.pointOfContact = { clamp(circle.pos.x, rect.min().x, rect.max().x), clamp(circle.pos.y, rect.min().y, rect.max().y) };

	if (cd.pointOfContact == circle.pos) {
		float dX = (cd.pointOfContact.x - rect.min().x < rect.max().x - cd.pointOfContact.x) ? rect.min().x : rect.max().x;
		float dY = (cd.pointOfContact.y - rect.min().y < rect.max().y - cd.pointOfContact.y) ? rect.min().y : rect.max().y;

		if (abs(dX - cd.pointOfContact.x) < abs(dY - cd.pointOfContact.y)) cd.pointOfContact.x = dX;
		else															   cd.pointOfContact.y = dY;
	}

	float dist =	pow(circle.pos.x - cd.pointOfContact.x, 2) + pow(circle.pos.y - cd.pointOfContact.y, 2);
	float radius =	pow(circle.radius, 2);

	cd.penetrationDepth = radius - dist;
	if (dist < radius) cd.inOverlap = true;
	cd.collisionNormal = (circle.pos - cd.pointOfContact).normal();

	return cd;
}
AABB operator*(const Mat3 &m, const AABB &a)
{
	Vec2 omin = a.min();
	Vec2 omax = a.max();

	Vec2 rmin = m[2].xy;
	Vec2 rmax = m[2].xy;

	float p, q;

	for (unsigned j = 0; j < 2; ++j)
		for (unsigned i = 0; i < 2; ++i)
		{
			p = omin[i] * m[i][j];
			q = omax[i] * m[i][j];

			if (p < q) std::swap(p, q);
			rmin[j] += p;
			rmax[j] += q;
		}
	return{ (rmin + rmax) / 2, (rmin - rmax) / 2 };
}
Beispiel #25
0
Frustum::IntersectResult Frustum::intersectAABB(const AABB& aabb) const
{
    IntersectResult result = IntersectResult::INSIDE;
    int indexFirst = static_cast<int>(FrustumPlane::FRUSTUM_NEAR);
    int indexNumber = static_cast<int>(FrustumPlane::FRUSTUM_NUMBER);
    
    for(int planeIndex = indexFirst; planeIndex < indexNumber; ++planeIndex)
    {
        kmPlane plane = _frustumPlanes[static_cast<FrustumPlane>(planeIndex)];
        kmVec3 normal = {plane.a, plane.b, plane.c};
        kmVec3Normalize(&normal, &normal);
        kmVec3 positivePoint = aabb.getPositivePoint(normal);
        kmVec3 negativePoint = aabb.getNegativePoint(normal);
        
        if(kmPlaneDotCoord(&plane, &positivePoint) < 0)
            return IntersectResult::OUTSIDE;
        if(kmPlaneDotCoord(&plane, &negativePoint) < 0)
            result = IntersectResult::INTERSECT;
    }
    
    return result;
}
Beispiel #26
0
	Vec3 GetTargetPos( SActivationInfo* pActInfo )
	{
		EntityId targetId = GetPortEntityId(pActInfo, IN_TARGETID);

		Vec3 targetPos(0,0,0);

		if (targetId)
		{
			IEntity* pTarget = gEnv->pEntitySystem->GetEntity(targetId);
			if (pTarget)
			{
				AABB box;
				pTarget->GetWorldBounds(box);
				targetPos = box.GetCenter();
			}        
		}
		else
		{
			targetPos = GetPortVec3(pActInfo, IN_TARGETPOS);		
		}
		return targetPos;
	}
Beispiel #27
0
int Frustum::boxInFrustum(const AABB& bbox)
{
	int result = INSIDE;
	for(unsigned int i=0; i<PLANECOUNT; i++)
	{
		if(planes[i]->isBehind(bbox.positiveVertex(planes[i]->normal)))
		{
			return OUTSIDE;
		}
	}

	return result;
}
Beispiel #28
0
/**
 * @sa ProcessModels
 */
static void ProcessSubModel (int entityNum)
{
    const entity_t* e;
    int start, end;
    tree_t* tree;
    bspbrush_t* list;
    AABB aabb;

    BeginModel(entityNum);

    e = &entities[entityNum];
#if 0
    Com_Printf("Processing entity: %i into model %i (%s:%s)\n", entityNum, curTile->nummodels, e->epairs->key, e->epairs->value);
#endif

    start = e->firstbrush;
    end = start + e->numbrushes;

    aabb.reset();
    aabb.expand(MAX_WORLD_WIDTH);

    /* every level (-1) */
    list = MakeBspBrushList(start, end, -1, aabb);
    if (!config.nocsg)
        list = ChopBrushes(list);
    tree = BuildTree(list, aabb.mins, aabb.maxs);
    assert(tree);
    assert(tree->headnode);
    if (tree->headnode->planenum == PLANENUM_LEAF)
        Sys_Error("No head node bmodel of %s (%i)\n", ValueForKey(e, "classname"), entityNum);
    MakeTreePortals(tree);
    MarkVisibleSides(tree, start, end);
    MakeFaces(tree->headnode);
    FixTjuncs(tree->headnode);
    curTile->models[curTile->nummodels].headnode = WriteBSP(tree->headnode);
    FreeTree(tree);

    EndModel();
}
Beispiel #29
0
void Flunence2ParticleProcess::init(Float emitterArea, const AABB &volumeAABB, const Vector3u &volumeReso)
{
    switch ( m_emitterMode )
    {
    case Fluence2ParticleTracer::EMITTER_AREA:
        m_surfScale = 1.0f/(emitterArea*M_PI*static_cast<Float>(m_workCount));
        //m_volScale = static_cast<Float>(volumeReso.x*volumeReso.y*volumeReso.z)/
        //    (static_cast<Float>(m_workCount)*volumeAABB.getVolume());
        m_volScale = static_cast<Float>(volumeReso.x*volumeReso.y*volumeReso.z)/
            (emitterArea*M_PI*static_cast<Float>(m_workCount)*volumeAABB.getVolume());
        break;

    case Fluence2ParticleTracer::EMITTER_POINT:
        m_surfScale = 1.0f/static_cast<Float>(m_workCount);
        m_volScale = static_cast<Float>(volumeReso.x*volumeReso.y*volumeReso.z)/
            (static_cast<Float>(m_workCount)*volumeAABB.getVolume());
        break;

    default:
        m_surfScale = m_volScale = 1.0f;
    }
}
Beispiel #30
0
_Use_decl_annotations_
void BIH::Query(const AABB& test, uint32_t nodeIndex, uint32_t* numTriangles)
{
    Node& node = _nodes[nodeIndex];
    if (node.Axis == 3)
    {
        // Leaf
        *numTriangles += node.NumTriangles;
    }
    else
    {
        if (*(&test.GetMin().x + node.Axis) < node.Max)
        {
            Query(test, nodeIndex + 1, numTriangles);
        }

        if (*(&test.GetMax().x + node.Axis) > node.Min)
        {
            Query(test, node.MaxNode, numTriangles);
        }
    }
}