示例#1
0
bool cBSPTree::RayCastToBoundary3(cRay &ret,  const cCoord3& start, const cCoord3& direction )
{

	if(!CheckBoxHit(start, direction)){
		return false;
	}
		p4::Log::TMI("%s Raycast", mName);
	float min_bound = 0.0f;
	float max_bound = MaxFloat();
	if(mBoundingBox.CheckWithin(start)){
		mBoundingBox.RayIntersection(max_bound, start, direction);
	}
	else{
		mBoundingBox.RayIntersection(min_bound, start, direction);
		mBoundingBox.RayIntersection(max_bound, start+(min_bound+0.01f)*direction, direction);
		max_bound+=min_bound+0.01f;
	}
	p4::Log::TMI("ray bounds = (%f, %f)", min_bound, max_bound );
	cRay last_result(direction, 0.0f);
	float current_distance = min_bound+cBSPNode::kEqualThreshold*0.5f;
	cCoord3 best_plane = direction;
	cCoord3 p = start+current_distance*direction;
	while(mBoundingBox.CheckWithin(p) && IsOutsidePoly(last_result, p, direction, HeadNode())){
		current_distance+=GreaterOf(last_result.mLength, cBSPNode::kEqualThreshold*0.5f);
		best_plane = last_result.mDirection;
		p4::Log::TMI("current result = %f, last result = %f", current_distance, last_result.mLength);
		p = start+(current_distance+cBSPNode::kEqualThreshold*0.5f)*direction;
	}
	p4::Log::TMI("Ready to return %f", current_distance);
	/*
	for (int i = 0; i < 100; i++)
	{
		const float d = (max_bound-min_bound)*(i/100.0f)+min_bound;
		p=start+d*direction;
		bool is_out = IsOutsidePoly(last_result, p, direction, HeadNode());
		if(is_out){
			p4::Log::Debug("%d\t OUT current result = %f, last result = %f",i, d, last_result);
		}
		else{
			p4::Log::Debug("%d\t IN  current result = %f, last result = %f",i, d, last_result);
		}
	}
	*/
	p = start+(current_distance)*direction;
	p4::Log::TMI("Done result = %f, last result = %f", current_distance, last_result.mLength);
	if( mBoundingBox.CheckWithin(p)){
		cBSPNode* best = ClosestContainingPlane(p+direction*cBSPNode::kEqualThreshold*0.5f, direction, HeadNode());
		if(best == NULL){
			return false;
		}
		ret.mLength = current_distance;
		ret.mDirection = best->GetDividingPlane().NormalVec();
		return true;
	}
	p4::Log::TMI("Not within Bounds? result = %f, last result = %f", current_distance, last_result.mLength);
	return false;
}
void convert_to_long_result(mpfr_class const& r, I& result)
{
   result = 0;
   I last_result(0);
   mpfr_class t(r);
   double term;
   do
   {
      term = real_cast<double>(t);
      last_result = result;
      result += static_cast<I>(term);
      t -= term;
   }while(result != last_result);
}