/** Checks how the box intersects with the sphere.
*/
Intersection intersect( const Sphere &one, const AxisAlignedBox &two )
{
    // Null box?
    if (two.isNull()) return OUTSIDE;
    if (two.isInfinite()) return INTERSECT;

    float sradius = one.getRadius();

    sradius *= sradius;

    Vector3 scenter = one.getCenter();

    const Vector3& twoMin = two.getMinimum();
    const Vector3& twoMax = two.getMaximum();

    float s, d = 0;

    Vector3 mndistance = ( twoMin - scenter );
    Vector3 mxdistance = ( twoMax - scenter );

    if ( mndistance.squaredLength() < sradius &&
            mxdistance.squaredLength() < sradius )
    {
        return INSIDE;
    }

    //find the square of the distance
    //from the sphere to the box
    for ( int i = 0 ; i < 3 ; i++ )
    {
        if ( scenter[ i ] < twoMin[ i ] )
        {
            s = scenter[ i ] - twoMin[ i ];
            d += s * s;
        }

        else if ( scenter[ i ] > twoMax[ i ] )
        {
            s = scenter[ i ] - twoMax[ i ];
            d += s * s;
        }

    }

    bool partial = ( d <= sradius );

    if ( !partial )
    {
        return OUTSIDE;
    }

    else
    {
        return INTERSECT;
    }


}
Example #2
0
void ArcballTestApp::draw()
{
	CameraPersp &cam = ( mUsingCameraUi ) ? mDebugCam : mCam;
	gl::clear( Color( 0, 0.0f, 0.15f ) );
	gl::setMatrices( cam );

	// draw the earth
	gl::enableDepthRead();
	gl::enableDepthWrite();
	gl::translate( mEarthSphere.getCenter() );
	gl::rotate( mArcball.getQuat() );
	mEarthTex->bind();
	mEarth->draw();

	// draw constraint axis
	if( mArcball.isUsingConstraint() ) {
		gl::setMatrices( cam );
		gl::color( 1, 1, 0 );
		gl::translate( mEarthSphere.getCenter() );
		gl::rotate( glm::rotation( vec3( 0, 1, 0 ), mArcball.getConstraintAxis() ) );
		mConstraintAxis->draw();
	}

	gl::disableDepthRead();

	// draw from vector marker
	gl::setMatrices( cam );
	gl::color( 0, 1, 0.25f );
	gl::translate( mEarthSphere.getCenter() + mArcball.getFromVector() * mEarthSphere.getRadius() );
	mMarker->draw();

	// draw to vector marker
	gl::setMatrices( cam );
	gl::color( 1, 0.5f, 0.25f );
	gl::translate( mEarthSphere.getCenter() + mArcball.getToVector() * mEarthSphere.getRadius() );
	mMarker->draw();

	// draw the elliptical axes
	gl::setMatricesWindow( getWindowSize() );
	gl::color( 1, 0, 0 );
	vec2 center, axisA, axisB;
	mCam.calcScreenProjection( mEarthSphere, getWindowSize(), &center, &axisA, &axisB );
	gl::drawLine( center - axisA, center + axisA );
	gl::drawLine( center - axisB, center + axisB );
}
ContainmentResult	TestPointSphere	( Vector const & V,
									  Sphere const & S )
{
	real radiusSquared = S.getRadius() * S.getRadius();

	real distanceSquared = (V-S.getCenter()).magnitudeSquared();

	return Containment1d::TestFloatLess(distanceSquared,radiusSquared);
}
AxialBox EncloseABox ( Sphere const & sphere )
{
	float r = sphere.getRadius();
	Vector c = sphere.getCenter();

	Vector d(r,r,r);

	return AxialBox( c + d, c - d );
}
ContainmentResult TestSphereOBox        ( Sphere const & S, OrientedBox const & B )
{
	if(Test(S.getCenter(),B) == CR_Inside)
	{
		return CR_Overlap;
	}
	else
	{
		Vector closest = Distance3d::ClosestPointOBox( S.getCenter(), B );

		if(TestPointSphere(closest,S) == CR_Inside)
		{
			return CR_Overlap;
		}
		else
		{
			return CR_Outside;
		}
	}
}
Sphere EncloseSphere ( Sphere const & A, Sphere const & B )
{
	if( Containment::isContainment(TestSphereSphere(A,B)) ) return B;
	if( Containment::isContainment(TestSphereSphere(B,A)) ) return A;

	// ----------
	
	Vector normal = B.getCenter() - A.getCenter();
	
	IGNORE_RETURN( normal.normalize() );

	Vector pointA = A.getCenter() - normal * A.getRadius();
	Vector pointB = B.getCenter() + normal * B.getRadius();

	Vector center = Vector::midpoint(pointA,pointB);

	real radius = (pointB - pointA).magnitude() / 2.0f;

	return Sphere(center,radius);
}
static void View(Camera* camera, const AxisAlignedBox& aabb, const Sphere& sphere)
{
	float nearClip = (sphere.getRadius() > 1)? 1 : 0.05;
	float farClip = sphere.getRadius()*10000.0f;

	camera->setNearClipDistance(nearClip);
	camera->setFarClipDistance(farClip);

	// tan (fov/2.0) = r/d => d = r/tan(fov/2.0)
	float distance = sphere.getRadius()/Math::Tan(camera->getFOVy()/2.0f);

	camera->setPosition(sphere.getCenter() - (camera->getDirection().normalisedCopy()*distance));
}
Example #8
0
CameraPersp	CameraPersp::getFrameSphere( const Sphere &worldSpaceSphere, int maxIterations ) const
{
	CameraPersp result = *this;
	result.setEyePoint( worldSpaceSphere.getCenter() - result.mViewDirection * getCenterOfInterest() );
	
	float minDistance = 0.01f, maxDistance = 100000.0f;
	float curDistance = getCenterOfInterest();
	for( int i = 0; i < maxIterations; ++i ) {
		float curRadius = result.getScreenRadius( worldSpaceSphere, 2.0f, 2.0f );
		if( curRadius < 1.0f ) { // we should get closer
			maxDistance = curDistance;
			curDistance = ( curDistance + minDistance ) * 0.5f;
		}
		else { // we should get farther
			minDistance = curDistance;
			curDistance = ( curDistance + maxDistance ) * 0.5f;			
		}
		result.setEyePoint( worldSpaceSphere.getCenter() - result.mViewDirection * curDistance );
	}
	
	result.setCenterOfInterest( result.getEyePoint().distance( worldSpaceSphere.getCenter() ) );
	return result;
}
Example #9
0
bool Math::intersected(const Plane& plane, const Sphere& sphere)
{
   Vector3 point = sphere.getCenter();
   Real dis = plane.getDistance(point);

   if(dis < sphere.getRadius())
   {
      return true;
   }
   else
   {
      return false;
   }

}
Example #10
0
void ParticleObject::add(const Sphere<float>& sphere, const float diameter, const float charge)
{
	const auto bb = sphere.getBoundingBox();

	for (auto x = bb.getMinX(); x <= bb.getMaxX(); x+= diameter) {
		for (auto y = bb.getMinY(); y <= bb.getMaxY(); y += diameter) {
			for (auto z = bb.getMinZ(); z <= bb.getMaxZ(); z+= diameter) {
				const Vector3d<float> pos(x, y, z);
				if (sphere.isInner(pos)) {
					const auto density = (sphere.getRadius() - sphere.getCenter().getDistance(pos)) * charge;
					particles.push_back(new Particle(pos, density, diameter * 0.5f));
				}
			}
		}
	}
	sort();
}
Example #11
0
void Collide::pointSphereCollide(const Body * point_, const Body * sphere_)
{
	Point *point = (Point*)point_;
	Sphere *sphere = (Sphere*)sphere_;

	float distance = 0.0f;
	distance = (point->getPoint() - sphere->getCenter()).Length();

	setCollide(distance < sphere->getRadius());
	setDistance(distance - sphere->getRadius());

	// compute the response vectors
	Vector3 responseObject1 = point_->getCenter() - sphere_->getCenter();
	Vector3 responseObject2 = sphere_->getCenter() - point_->getCenter();
	setResponseObject1(responseObject1);
	setResponseObject2(responseObject2);
}
Example #12
0
bool Math::intersected(const Ray& ray, const Sphere& sphere)
{
   Vector3 t = ray.getOrien();
   Vector3 origin = ray.getOrigin();
   Vector3 center = sphere.getCenter();
   Vector3 s = center - origin;
   Real d = (s.crossProduct(t)).length();

   if(d <= sphere.getRadius())
   {
      return true;
   }
   else
   {
      return false;

   }
}
	void setShaderVariables(GLuint shaderProg)
	{
		GLfloat projMatrix[16];
		GLfloat viewMatrix[16];
		glGetFloatv(GL_PROJECTION_MATRIX, projMatrix);
		glGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix);
		
		double *center = ball.getCenter();

		if(GL20Support)
		{
			glUniform3f(glGetUniformLocation(shaderProg, "ballPos"),center[0], center[1], center[2]);
		}
		else
		{
			//glUniform3fvARB(glGetUniformLocationARB(shaderProg, "ballPos"), 3, (float*)ball.getCenter());
		}
	}
Example #14
0
    //-----------------------------------------------------------------------
    std::pair<bool, Real> Math::intersects(const Ray& ray, const Sphere& sphere, 
        bool discardInside)
    {
        const Vector3& raydir = ray.getDirection();
        // Adjust ray origin relative to sphere center
        const Vector3& rayorig = ray.getOrigin() - sphere.getCenter();
        Real radius = sphere.getRadius();

        // Check origin inside first
        if (rayorig.squaredLength() <= radius*radius && discardInside)
        {
            return std::pair<bool, Real>(true, (Real)0);
        }

        // Mmm, quadratics
        // Build coeffs which can be used with std quadratic solver
        // ie t = (-b +/- sqrt(b*b + 4ac)) / 2a
        Real a = raydir.dotProduct(raydir);
        Real b = 2 * rayorig.dotProduct(raydir);
        Real c = rayorig.dotProduct(rayorig) - radius*radius;

        // Calc determinant
        Real d = (b*b) - (4 * a * c);
        if (d < 0)
        {
            // No intersection
            return std::pair<bool, Real>(false, (Real)0);
        }
        else
        {
            // BTW, if d=0 there is one intersection, if d > 0 there are 2
            // But we only want the closest one, so that's ok, just use the 
            // '-' version of the solver
            Real t = ( -b - Math::Sqrt(d) ) / (2 * a);
            if (t < 0)
                t = ( -b + Math::Sqrt(d) ) / (2 * a);
            return std::pair<bool, Real>(true, (Real)t);
        }


    }
Example #15
0
void Collide::raySphereCollide(const Body * ray_, const Body * sphere_)
{
	Ray *ray = (Ray*)ray_;
	Sphere *sphere = (Sphere*)sphere_;
	Vector3 vec = ray->getStart() - sphere->getCenter();
	setCollide(true);
	setDistance(0.0f);
	float fB = vec.Dot(ray->getDir());
	float fC = vec.Dot(vec) - sphere->getRadius()*sphere->getRadius();
	if (fC > 0.0f && fB > 0.0f)
		setCollide(false);
	float fDisc = fB*fB - fC;
	if (fDisc < 0.0f)
		setCollide(false);

	// compute the response vectors
	Vector3 responseObject1 = ray_->getCenter()- sphere_->getCenter();
	Vector3 responseObject2 = sphere_->getCenter() - ray_->getCenter();
	setResponseObject1(responseObject1);
	setResponseObject2(responseObject2);
}
Example #16
0
//==============================================================================
static Bool test(const Aabb& aabb, const Sphere& s)
{
	const Vec4& c = s.getCenter();

	// find the box's closest point to the sphere
	Vec4 cp(0.0); // Closest Point
	for(U i = 0; i < 3; i++)
	{
		// if the center is greater than the max then the closest
		// point is the max
		if(c[i] > aabb.getMax()[i])
		{
			cp[i] = aabb.getMax()[i];
		}
		else if(c[i] < aabb.getMin()[i]) // relative to the above
		{
			cp[i] = aabb.getMin()[i];
		}
		else
		{
			// the c lies between min and max
			cp[i] = c[i];
		}
	}

	F32 rsq = s.getRadius() * s.getRadius();

	// if the c lies totally inside the box then the sub is the zero,
	// this means that the length is also zero and thus its always smaller
	// than rsq
	Vec4 sub = c - cp;

	if(sub.getLengthSquared() <= rsq)
	{
		return true;
	}

	return false;
}
Example #17
0
//==============================================================================
Bool test(const LineSegment& ls, const Sphere& s)
{
	const Vec4& v = ls.getDirection();
	Vec4 w0 = s.getCenter() - ls.getOrigin();
	F32 w0dv = w0.dot(v);
	F32 rsq = s.getRadius() * s.getRadius();

	if(w0dv < 0.0) // if the ang is >90
	{
		return w0.getLengthSquared() <= rsq;
	}

	Vec4 w1 = w0 - v; // aka center - P1, where P1 = seg.origin + seg.dir
	F32 w1dv = w1.dot(v);

	if(w1dv > 0.0) // if the ang is <90
	{
		return w1.getLengthSquared() <= rsq;
	}

	// the big parenthesis is the projection of w0 to v
	Vec4 tmp = w0 - (v * (w0.dot(v) / v.getLengthSquared()));
	return tmp.getLengthSquared() <= rsq;
}
ContainmentResult  TestSphereCylinder ( Sphere const & S,
									    Cylinder const & C )
{
	Vector delta = C.getBase() - S.getCenter();
	delta.y = 0;

	real dist = delta.magnitude();

	Range SD( dist - S.getRadius(), dist + S.getRadius() );

	Range CD( -C.getRadius(), C.getRadius() );

	ContainmentResult hTest = Containment1d::TestRangeRange( SD, CD );
	ContainmentResult hTest2 = Containment1d::TestFloatRange( dist, CD );

	ContainmentResult vTest = Containment1d::TestRangeRange( S.getRangeY(), C.getRangeY() );
	ContainmentResult cTest = Containment1d::TestFloatRange( S.getCenter().y, C.getRangeY() );

	// ----------

	if(hTest == CR_Outside)
	{
		// Sphere can't possibly touch the cylinder

		return CR_Outside;
	}
	else if((hTest == CR_TouchingOutside) || (hTest == CR_Boundary))
	{
		// Sphere is touching the outside of the cylinder's tube if its
		// center is inside the vertical range of the cylinder

		if((cTest == CR_Inside) || (cTest == CR_Boundary))
		{
			return CR_TouchingOutside;
		}
		else
		{
			return CR_Outside;
		}
	}
	else if((hTest == CR_Inside) || (hTest == CR_TouchingInside))
	{
		// Sphere is in the tube of the cylinder. It touches the cylinder
		// if its vertical range touches the vertical range of the cylinder

		return Containment::ComposeAxisTests(hTest,vTest);
	}
	else
	{
		// hTest == CR_Overlap

		if(vTest == CR_Outside)
		{
			return CR_Outside;
		}
		else if((vTest == CR_Inside) || (vTest == CR_TouchingInside))
		{
			return CR_Overlap;
		}
		else if (vTest == CR_Boundary)
		{
			// This really shouldn't be happening
			return CR_Boundary;
		}
		else if (vTest == CR_TouchingOutside)
		{
			if(hTest2 == CR_Inside)
			{
				// Sphere is touching a cap of the cylinder
				return CR_TouchingOutside;
			}
			else if(hTest2 == CR_Boundary)
			{
				// Sphere is touching the edge of the cap of the cylinder
				return CR_TouchingOutside;
			}
			else
			{
				// Sphere isn't touching the cap
				return CR_Outside;
			}
		}
		else
		{
			// vTest == CR_Overlap

			if((cTest == CR_Inside) || (cTest == CR_Boundary))
			{
				// The ranges overlap vertically and horizontally, and the center of
				// the sphere is inside the vertical range - the sphere overlaps the
				// cylinder

				return CR_Overlap;
			}
			else
			{
				// The sphere is inside both ranges, but its center is outside both
				// ranges. The sphere overlaps the cylinder if the closest point
				// on the cylinder is inside the sphere.

				Vector closestPoint = Distance3d::ClosestPointCylinder(S.getCenter(),C);

				ContainmentResult result = TestPointSphere(closestPoint,S);

				if(result == CR_Outside)
				{
					return CR_Outside;
				}
				else if(result == CR_Boundary)
				{
					return CR_TouchingOutside;
				}
				else
				{
					return CR_Overlap;
				}
			}
		}
	}
}
Example #19
0
	bool Frustum::projectSphere(const Sphere& sphere,
		Real* left, Real* top, Real* right, Real* bottom) const
	{
		// 变换光源位置到相机空间

		updateView();
		Vector3 eyeSpacePos = mViewMatrix.transformAffine(sphere.getCenter()); //将球中心坐标转到观察空间中

		// 初始化
		*left = *bottom = -1.0f;
		*right = *top = 1.0f;

		if (eyeSpacePos.z < 0)
		{
			updateFrustum();
			const Matrix4& projMatrix = getProjectionMatrix();
			Real r = sphere.getRadius();
			Real rsq = r * r;  //半径的平方


			if (eyeSpacePos.squaredLength() <= rsq)
				return false;

			Real Lxz = Math::Sqr(eyeSpacePos.x) + Math::Sqr(eyeSpacePos.z);  //设原点O,球心P, 向量Vop在XZ平面上的投影
			Real Lyz = Math::Sqr(eyeSpacePos.y) + Math::Sqr(eyeSpacePos.z);  //设原点O,球心P, 向量Vop在YZ平面上的投影

			// 用点法式 找出球体切平面
			// 首先XZ 
			// 计算二次根判别式: b*b - 4ac
			// x = Nx
			// a = Lx^2 + Lz^2
			// b = -2rLx
			// c = r^2 - Lz^2
			Real a = Lxz;
			Real b = -2.0f * r * eyeSpacePos.x;
			Real c = rsq - Math::Sqr(eyeSpacePos.z);
			Real D = b*b - 4.0f*a*c;

			// 两个根
			if (D > 0)
			{
				Real sqrootD = Math::Sqrt(D);
				// 解除二次方获取法线的分量
				Real Nx0 = (-b + sqrootD) / (2 * a);
				Real Nx1 = (-b - sqrootD) / (2 * a);

				// 取得Z
				Real Nz0 = (r - Nx0 * eyeSpacePos.x) / eyeSpacePos.z;
				Real Nz1 = (r - Nx1 * eyeSpacePos.x) / eyeSpacePos.z;

				// 获取切点
				// 只考虑相机前面的切点
				Real Pz0 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz0 / Nx0) * eyeSpacePos.x));
				if (Pz0 < 0)
				{
					// 投影在近剪裁平面在世界空间的点
					Real nearx0 = (Nz0 * mNearDist) / Nx0;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 relx0 = projMatrix * Vector3(nearx0, 0, -mNearDist);

					//找出这是左边还是右边
					Real Px0 = -(Pz0 * Nz0) / Nx0;
					if (Px0 > eyeSpacePos.x)
					{
						*right = std::min(*right, relx0.x);
					}
					else
					{
						*left = std::max(*left, relx0.x);
					}
				}
				Real Pz1 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz1 / Nx1) * eyeSpacePos.x));
				if (Pz1 < 0)
				{
					//投影在近剪裁平面在世界空间的点
					Real nearx1 = (Nz1 * mNearDist) / Nx1;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 relx1 = projMatrix * Vector3(nearx1, 0, -mNearDist);

					//找出这是左边还是右边
					Real Px1 = -(Pz1 * Nz1) / Nx1;
					if (Px1 > eyeSpacePos.x)
					{
						*right = std::min(*right, relx1.x);
					}
					else
					{
						*left = std::max(*left, relx1.x);
					}
				}
			}


			// 现在是 YZ 平面
			// 计算二次方根判别式: b*b - 4ac
			// x = Ny
			// a = Ly^2 + Lz^2
			// b = -2rLy
			// c = r^2 - Lz^2
			a = Lyz;
			b = -2.0f * r * eyeSpacePos.y;
			c = rsq - Math::Sqr(eyeSpacePos.z);
			D = b*b - 4.0f*a*c;

			//两个根
			if (D > 0)
			{
				Real sqrootD = Math::Sqrt(D);
				// 解除二次根获得法线的分量
				Real Ny0 = (-b + sqrootD) / (2 * a);
				Real Ny1 = (-b - sqrootD) / (2 * a);

				// 从这里取得Z
				Real Nz0 = (r - Ny0 * eyeSpacePos.y) / eyeSpacePos.z;
				Real Nz1 = (r - Ny1 * eyeSpacePos.y) / eyeSpacePos.z;

				// 获取切点
				// 只考虑相机前面的切点
				Real Pz0 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz0 / Ny0) * eyeSpacePos.y));
				if (Pz0 < 0)
				{
					//投影在近剪裁平面在世界空间的点
					Real neary0 = (Nz0 * mNearDist) / Ny0;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 rely0 = projMatrix * Vector3(0, neary0, -mNearDist);

					//找出这是左边还是右边
					Real Py0 = -(Pz0 * Nz0) / Ny0;
					if (Py0 > eyeSpacePos.y)
					{
						*top = std::min(*top, rely0.y);
					}
					else
					{
						*bottom = std::max(*bottom, rely0.y);
					}
				}
				Real Pz1 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz1 / Ny1) * eyeSpacePos.y));
				if (Pz1 < 0)
				{
					//投影在近剪裁平面在世界空间的点
					Real neary1 = (Nz1 * mNearDist) / Ny1;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 rely1 = projMatrix * Vector3(0, neary1, -mNearDist);

					//找出这是左边还是右边
					Real Py1 = -(Pz1 * Nz1) / Ny1;
					if (Py1 > eyeSpacePos.y)
					{
						*top = std::min(*top, rely1.y);
					}
					else
					{
						*bottom = std::max(*bottom, rely1.y);
					}
				}
			}
		}

		return (*left != -1.0f) || (*top != 1.0f) || (*right != 1.0f) || (*bottom != -1.0f);

	}
Example #20
0
bool TestSpherePlane ( Sphere const & A, Plane3d const & B )
{
	float dist = std::abs(Distance3d::DistancePointPlane(A.getCenter(),B));

	return dist <= A.getRadius();
}
Example #21
0
bool TestYLineSphere ( Vector const & V, Sphere const & S )
{
	return Distance2d::Distance2PointPoint(V,S.getCenter()) < sqr(S.getRadius());
}
Example #22
0
//==============================================================================
static Bool test(const Sphere& a, const Sphere& b)
{
	F32 tmp = a.getRadius() + b.getRadius();
	return (a.getCenter() - b.getCenter()).getLengthSquared() <= tmp * tmp;
}
Example #23
0
__global__ void
gpuWalkWithSentinel(int seed, DistanceEvaluator* distance,
		    ResultsCalculator* results)
{
  unsigned int index = blockIdx.x * blockDim.x + threadIdx.x;
  CudaRandom rand(index, seed);
  Sphere<double> boundingSphere = distance->boundingSphere();
  
  results->gpuConstructor(index);

  Vector3<double> startingPosition =
    RandomPoint::generate(&rand, &boundingSphere);


  while ((*distance)(startingPosition) < epsilon){
    results->recordHit(index, startingPosition, startingPosition);
    Vector3<double> startingPosition =
	RandomPoint::generate(&rand, &boundingSphere);
  }
  
  Vector3<double> position = startingPosition;
  
  bool replace = false;

  bool done = false;
  
  size_t walks = 0;
  
  //while (walks < walksPerThread)
  while (!done)
  {
    Sphere<double> displacementSphere{position, (*distance)(position)};
    position =  RandomPoint::generate(&rand, &displacementSphere);
    
    // Check for escape!
    double centerDistSqr =
      (position - boundingSphere.getCenter()).getMagnitudeSqr();

    if (centerDistSqr > boundingSphere.getRadiusSqr())
    {
      //walker left bounding sphere
    
      double alpha = boundingSphere.getRadius() / sqrt(centerDistSqr);
      
      if (rand.getRandInRange(0, 1) > (1 - alpha))
      {
    	//walker is replaced
	position = BiasedPoint::generate(&rand, &boundingSphere,
					 &position, alpha);
      }
      else
      {
	results->recordMiss(index);
	replace = true;
      }
    }

    if ((*distance)(position) < 0.0001)
    {
      results->recordHit(index, startingPosition, position);
      replace = true;
    }

    if (replace)
    {
      if (results->runFinished())
      {
	done = true;
      }
      else
      {
	++walks;
	replace = false;
	startingPosition = RandomPoint::generate(&rand, &boundingSphere);
	
	while ((*distance)(startingPosition) < epsilon){
	  results->recordHit(index, startingPosition, startingPosition);
	  Vector3<double> startingPosition =
	    RandomPoint::generate(&rand, &boundingSphere);
	}

	position = startingPosition;
      }
    }
  }
}
Example #24
0
    //---------------------------------------------------------------------
    bool Frustum::projectSphere(const Sphere& sphere, 
        Real* left, Real* top, Real* right, Real* bottom) const
    {
		// See http://www.gamasutra.com/features/20021011/lengyel_06.htm
        // Transform light position into camera space

        updateView();
        Vector3 eyeSpacePos = mViewMatrix.transformAffine(sphere.getCenter());

		// initialise
		*left = *bottom = -1.0f;
		*right = *top = 1.0f;

        if (eyeSpacePos.z < 0)
        {
			updateFrustum();
			const Matrix4& projMatrix = getProjectionMatrix();
            Real r = sphere.getRadius();
			Real rsq = r * r;

            // early-exit
            if (eyeSpacePos.squaredLength() <= rsq)
                return false;

			Real Lxz = Math::Sqr(eyeSpacePos.x) + Math::Sqr(eyeSpacePos.z);
			Real Lyz = Math::Sqr(eyeSpacePos.y) + Math::Sqr(eyeSpacePos.z);

			// Find the tangent planes to the sphere
			// XZ first
			// calculate quadratic discriminant: b*b - 4ac
			// x = Nx
			// a = Lx^2 + Lz^2
			// b = -2rLx
			// c = r^2 - Lz^2
			Real a = Lxz;
			Real b = -2.0 * r * eyeSpacePos.x;
			Real c = rsq - Math::Sqr(eyeSpacePos.z);
			Real D = b*b - 4*a*c;

			// two roots?
			if (D > 0)
			{
				Real sqrootD = Math::Sqrt(D);
				// solve the quadratic to get the components of the normal
				Real Nx0 = (-b + sqrootD) / (2 * a);
				Real Nx1 = (-b - sqrootD) / (2 * a);
				
				// Derive Z from this
				Real Nz0 = (r - Nx0 * eyeSpacePos.x) / eyeSpacePos.z;
				Real Nz1 = (r - Nx1 * eyeSpacePos.x) / eyeSpacePos.z;

				// Get the point of tangency
				// Only consider points of tangency in front of the camera
				Real Pz0 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz0 / Nx0) * eyeSpacePos.x));
				if (Pz0 < 0)
				{
					// Project point onto near plane in worldspace
					Real nearx0 = (Nz0 * mNearDist) / Nx0;
					// now we need to map this to viewport coords
					// use projection matrix since that will take into account all factors
					Vector3 relx0 = projMatrix * Vector3(nearx0, 0, -mNearDist);

					// find out whether this is a left side or right side
					Real Px0 = -(Pz0 * Nz0) / Nx0;
					if (Px0 > eyeSpacePos.x)
					{
						*right = std::min(*right, relx0.x);
					}
					else
					{
						*left = std::max(*left, relx0.x);
					}
				}
				Real Pz1 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz1 / Nx1) * eyeSpacePos.x));
				if (Pz1 < 0)
				{
					// Project point onto near plane in worldspace
					Real nearx1 = (Nz1 * mNearDist) / Nx1;
					// now we need to map this to viewport coords
					// use projection matrix since that will take into account all factors
					Vector3 relx1 = projMatrix * Vector3(nearx1, 0, -mNearDist);

					// find out whether this is a left side or right side
					Real Px1 = -(Pz1 * Nz1) / Nx1;
					if (Px1 > eyeSpacePos.x)
					{
						*right = std::min(*right, relx1.x);
					}
					else
					{
						*left = std::max(*left, relx1.x);
					}
				}
			}


			// Now YZ 
			// calculate quadratic discriminant: b*b - 4ac
			// x = Ny
			// a = Ly^2 + Lz^2
			// b = -2rLy
			// c = r^2 - Lz^2
			a = Lyz;
			b = -2.0 * r * eyeSpacePos.y;
			c = rsq - Math::Sqr(eyeSpacePos.z);
			D = b*b - 4*a*c;

			// two roots?
			if (D > 0)
			{
				Real sqrootD = Math::Sqrt(D);
				// solve the quadratic to get the components of the normal
				Real Ny0 = (-b + sqrootD) / (2 * a);
				Real Ny1 = (-b - sqrootD) / (2 * a);

				// Derive Z from this
				Real Nz0 = (r - Ny0 * eyeSpacePos.y) / eyeSpacePos.z;
				Real Nz1 = (r - Ny1 * eyeSpacePos.y) / eyeSpacePos.z;

				// Get the point of tangency
				// Only consider points of tangency in front of the camera
				Real Pz0 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz0 / Ny0) * eyeSpacePos.y));
				if (Pz0 < 0)
				{
					// Project point onto near plane in worldspace
					Real neary0 = (Nz0 * mNearDist) / Ny0;
					// now we need to map this to viewport coords
					// use projection matriy since that will take into account all factors
					Vector3 rely0 = projMatrix * Vector3(0, neary0, -mNearDist);

					// find out whether this is a top side or bottom side
					Real Py0 = -(Pz0 * Nz0) / Ny0;
					if (Py0 > eyeSpacePos.y)
					{
						*top = std::min(*top, rely0.y);
					}
					else
					{
						*bottom = std::max(*bottom, rely0.y);
					}
				}
				Real Pz1 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz1 / Ny1) * eyeSpacePos.y));
				if (Pz1 < 0)
				{
					// Project point onto near plane in worldspace
					Real neary1 = (Nz1 * mNearDist) / Ny1;
					// now we need to map this to viewport coords
					// use projection matriy since that will take into account all factors
					Vector3 rely1 = projMatrix * Vector3(0, neary1, -mNearDist);

					// find out whether this is a top side or bottom side
					Real Py1 = -(Pz1 * Nz1) / Ny1;
					if (Py1 > eyeSpacePos.y)
					{
						*top = std::min(*top, rely1.y);
					}
					else
					{
						*bottom = std::max(*bottom, rely1.y);
					}
				}
			}
        }

        return (*left != -1.0f) || (*top != 1.0f) || (*right != 1.0f) || (*bottom != -1.0f);

    }
Example #25
0
		static bool test( const Sphere< T > &sphere1, const Sphere< T > &sphere2 )
		{
			T centerDiffSqr = ( sphere1.getCenter() - sphere2.getCenter() ).getSquaredMagnitude();
			T combinedRadius = ( sphere1.getRadius() + sphere2.getRadius() );
			return ( centerDiffSqr < ( combinedRadius * combinedRadius ) );
		}
Example #26
0
void DebugDraw::draw(const Sphere& sphere, const Color& color, bool mesh) const
{
	Matrix4x4 modelMatrix;

	if (mesh)
	{
		if (!LineGeometryManager::getInstance()->getLineGeometry("Sphere").get())
		{
			return;
		}

		modelMatrix.identity();
		modelMatrix.translate(sphere.getCenter().getX(), sphere.getCenter().getY(), sphere.getCenter().getZ());
		modelMatrix.scale(sphere.getRadius(), sphere.getRadius(), sphere.getRadius());
		LineGeometryManager::getInstance()->getLineGeometry("Sphere")->draw(modelMatrix, color);
	}
	else
	{
		if (!LineGeometryManager::getInstance()->getLineGeometry("Circle").get())
		{
			return;
		}

		modelMatrix.identity();
		modelMatrix.translate(sphere.getCenter().getX(), sphere.getCenter().getY(), sphere.getCenter().getZ());
		modelMatrix.rotateRzRyRx(0.0f, 0.0f, 0.0f);
		modelMatrix.scale(sphere.getRadius(), sphere.getRadius(), sphere.getRadius());
		LineGeometryManager::getInstance()->getLineGeometry("Circle")->draw(modelMatrix, color);

		modelMatrix.identity();
		modelMatrix.translate(sphere.getCenter().getX(), sphere.getCenter().getY(), sphere.getCenter().getZ());
		modelMatrix.rotateRzRyRx(0.0f, 90.0f, 0.0f);
		modelMatrix.scale(sphere.getRadius(), sphere.getRadius(), sphere.getRadius());
		LineGeometryManager::getInstance()->getLineGeometry("Circle")->draw(modelMatrix, color);

		modelMatrix.identity();
		modelMatrix.translate(sphere.getCenter().getX(), sphere.getCenter().getY(), sphere.getCenter().getZ());
		modelMatrix.rotateRzRyRx(0.0f, 0.0f, 90.0f);
		modelMatrix.scale(sphere.getRadius(), sphere.getRadius(), sphere.getRadius());
		LineGeometryManager::getInstance()->getLineGeometry("Circle")->draw(modelMatrix, color);
	}
}
bool PathFinderManager::getSpawnPointInArea(const Sphere& area, Zone *zone, Vector3& point, bool checkPath) {
	SortedVector<ManagedReference<NavArea*>> areas;
	float radius = area.getRadius();
	const Vector3& center = area.getCenter();
	Vector3 flipped(center.getX(), center.getZ(), -center.getY());
	float extents[3] = {3, 5, 3};

	dtNavMeshQuery* query = getNavQuery();

	if (zone == NULL)
		return false;

	zone->getInRangeNavMeshes(center.getX(), center.getY(), &areas, true);

	if (areas.size() == 0) {
		Vector3 temp((frand() * 2.0f) - 1.0f, (frand() * 2.0f) - 1.0f, 0);
		Vector3 result = temp * (frand() * radius);
		point = center + result;
		point.setZ(CollisionManager::getWorldFloorCollision(point.getX(), point.getY(), zone, false));
		return true;
	}

	for (const auto& navArea : areas) {
		Vector3 polyStart;
		dtPolyRef startPoly;
		dtPolyRef ref;
		int status = 0;
		float pt[3];

		RecastNavMesh *mesh = navArea->getNavMesh();
		if (mesh == NULL)
			continue;

		ReadLocker rLocker(navArea);

		dtNavMesh *dtNavMesh = mesh->getNavMesh();
		if (dtNavMesh == NULL)
			continue;

		query->init(dtNavMesh, MAX_QUERY_NODES);

		if (!((status = query->findNearestPoly(flipped.toFloatArray(), extents, &m_spawnFilter, &startPoly, polyStart.toFloatArray())) & DT_SUCCESS))
			continue;

		for (int i=0; i<50; i++) {
			try {
				if (!((status = query->findRandomPointAroundCircle(startPoly, polyStart.toFloatArray(), radius, &m_spawnFilter,
																   frand, &ref, pt)) & DT_SUCCESS)) {
					continue;
				} else {
					point = Vector3(pt[0], -pt[2], CollisionManager::getWorldFloorCollision(pt[0], -pt[2], zone, false));

					Vector3 temp = point - center;
					float len = temp.length();
					if (len > radius) {
						float multiplier = (frand() * radius) / len;
						temp.setX(temp.getX() * multiplier);
						temp.setY(temp.getY() * multiplier);
						point = center + temp;

						point.setZ(CollisionManager::getWorldFloorCollision(point.getX(), point.getY(), zone, false));
					}

					if (checkPath) {
						if (!getRecastPath(center, point, navArea, nullptr, len, false)) {
							continue;
						}
					}

					return true;
				}
			} catch (Exception& exc) {
				error(exc.getMessage());
			}
		}
	}

	return false;
}
bool pointInSphere(const Vector3 &point, const Sphere& sphere) {
	return (point-sphere.getCenter()).length() < sphere.getRadius();
}
Example #29
0
bool FrustumT<T>::contains( const Sphere &sphere ) const
{
	return contains( Vec3T( sphere.getCenter() ), (T)sphere.getRadius() );
}
Example #30
0
bool FrustumT<T>::intersects( const Sphere &sphere ) const
{
	return intersects( Vec3T( sphere.getCenter() ), (T)sphere.getRadius() );
}