예제 #1
0
BoundingSphere LOD::computeBound() const
{
    if (_centerMode==USER_DEFINED_CENTER && _radius>=0.0f)
    {
        return BoundingSphere(_userDefinedCenter,_radius);
    }
    else if (_centerMode==UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED && _radius>=0.0f)
    {
        BoundingSphere bs = BoundingSphere(_userDefinedCenter,_radius);
        bs.expandBy(Group::computeBound());
        //alternative (used in TxpPagedLOD)
        // bs.expandRadiusBy(Group::computeBound());
        return bs;
    }
    else
    {
        return Group::computeBound();
    }
}
IntersectData BoundingSphere::IntersectBoundingSphere(const BoundingSphere& other) const
{
	//The radius is the distance from any point on the sphere to the center.
	//
	//Therefore, by adding the radius of two spheres together, the result is
	//the distance between the centers of the spheres when they are touching.
	float radiusDistance = m_radius + other.GetRadius();
	float centerDistance = (other.GetCenter() - m_center).Length();

	//Since the radiusDistance is the distance bwteen the centers of the 
	//spheres are when they're touching, you can subtract that from the
	//distance between the centers of the spheres to get the actual distance
	//between the two spheres.
	float distance = centerDistance - radiusDistance;

	//Spheres can only be intersecting if the distance between them is less
	//than 0.
	return IntersectData(distance < 0, distance);
}
ModelEntitySP PrimitiveEntityFactory::createConePrimitiveEntity(const string& name, float scaleX, float scaleY, float scaleZ, const SurfaceMaterialSP& surfaceMaterial, const vector<AnimationStackSP>& allAnimStacks) const
{
	ModelFactory modelFactory;

	GLUSshape shape;

	float halfExtend = 0.5f;
	float radius = 0.5f;
	uint32_t numberSlices = 32;
	uint32_t numberStacks = 32;

	glusCreateConef(&shape, halfExtend, radius, numberSlices, numberStacks);

	BoundingSphere boundingSphere;

	boundingSphere.setRadius(glusLengthf(halfExtend, radius, 0.0f));

	return ModelEntitySP(new ModelEntity(name, modelFactory.createModel(name, boundingSphere, shape, surfaceMaterial, allAnimStacks), scaleX, scaleY, scaleZ));
}
ModelEntitySP PrimitiveEntityFactory::createTorusPrimitiveEntity(const string& name, float scaleX, float scaleY, float scaleZ, const SurfaceMaterialSP& surfaceMaterial, const vector<AnimationStackSP>& allAnimStacks) const
{
	ModelFactory modelFactory;

	GLUSshape shape;

	float innerRadius = 0.25f;
	float outerRadius = 0.5f;
	uint32_t numberSlices = 32;
	uint32_t numberStacks = 32;

	glusCreateTorusf(&shape, innerRadius, outerRadius, numberSlices, numberStacks);

	BoundingSphere boundingSphere;

	boundingSphere.setRadius(outerRadius);

	return ModelEntitySP(new ModelEntity(name, modelFactory.createModel(name, boundingSphere, shape, surfaceMaterial, allAnimStacks), scaleX, scaleY, scaleZ));
}
예제 #5
0
파일: Transform.cpp 프로젝트: joevandyk/osg
BoundingSphere Transform::computeBound() const
{
    BoundingSphere bsphere = Group::computeBound();
    if (!bsphere.valid()) return bsphere;
    
    // note, NULL pointer for NodeVisitor, so compute's need
    // to handle this case gracefully, normally this should not be a problem.
    Matrix l2w;

    computeLocalToWorldMatrix(l2w,NULL);

    Vec3 xdash = bsphere._center;
    xdash.x() += bsphere._radius;
    xdash = xdash*l2w;

    Vec3 ydash = bsphere._center;
    ydash.y() += bsphere._radius;
    ydash = ydash*l2w;

    Vec3 zdash = bsphere._center;
    zdash.z() += bsphere._radius;
    zdash = zdash*l2w;


    bsphere._center = bsphere._center*l2w;

    xdash -= bsphere._center;
    float len_xdash = xdash.length();

    ydash -= bsphere._center;
    float len_ydash = ydash.length();

    zdash -= bsphere._center;
    float len_zdash = zdash.length();

    bsphere._radius = len_xdash;
    if (bsphere._radius<len_ydash) bsphere._radius = len_ydash;
    if (bsphere._radius<len_zdash) bsphere._radius = len_zdash;

    return bsphere;

}
예제 #6
0
BoundingSphere Switch::computeBound() const
{
    BoundingSphere bsphere;
    if (_children.empty())
    {
        return bsphere;
    }

    // note, special handling of the case when a child is an Transform,
    // such that only Transforms which are relative to their parents coordinates frame (i.e this group)
    // are handled, Transform relative to and absolute reference frame are ignored.

    BoundingBox bb;
    bb.init();
    for(unsigned int pos=0;pos<_children.size();++pos)
    {
        const osg::Transform* transform = _children[pos]->asTransform();
        if (!transform || transform->getReferenceFrame()==osg::Transform::RELATIVE_RF)
        {
            if( _values[pos] == true )
                bb.expandBy(_children[pos]->getBound());
        }
    }

    if (!bb.valid())
    {
        return bsphere;
    }

    bsphere._center = bb.center();
    bsphere._radius = 0.0f;
    for(unsigned int pos=0;pos<_children.size();++pos)
    {
        const osg::Transform* transform = _children[pos]->asTransform();
        if (!transform || transform->getReferenceFrame()==osg::Transform::RELATIVE_RF)
        {
            if( _values[pos] == true )
                bsphere.expandRadiusBy(_children[pos]->getBound());
        }
    }
    return bsphere;
}
예제 #7
0
    /*!
    * creates a BoundingSphere which encloses all given bvhNodes and adds all children
    * to this parent
    */
    void DeformableBvhNode::createBoundingSphere(const std::list<DeformableBvhNode*>& bvhNodes) {

        //std::cout << "DeformableBvhNode::createBoundingSphere(const std::list<DeformableBvhNode*>& bvhNodes)" << std::endl;

        BoundingSphere* bv = 0;

        for (std::list<DeformableBvhNode*>::const_iterator iter = bvhNodes.begin();
             iter != bvhNodes.end();
             ++iter) {

            if (bv == 0) {
                bv = new BoundingSphere(*((BoundingSphere*)((*iter)->getBoundingVolume())));

            } else {
                bv->mergeWith((BoundingSphere*)((*iter)->getBoundingVolume()));
            }
        }

        mBoundingVolume = bv;
    }
예제 #8
0
BoundingSphere Geode::computeBound() const
{
    BoundingSphere bsphere;

    _bbox.init();

    DrawableList::const_iterator itr;
    for(itr=_drawables.begin();
        itr!=_drawables.end();
        ++itr)
    {
        _bbox.expandBy((*itr)->getBound());
    }

    if (_bbox.valid())
    {
        bsphere.expandBy(_bbox);
    }
    return bsphere;
}
예제 #9
0
파일: PatchSet.cpp 프로젝트: 2php/osgearth
Node* PatchSet::createPatchGroup(const std::string& filename,
                                 PatchOptions* poptions)
{
    PatchGroup* pgroup = new PatchGroup;
    pgroup->setOptions(poptions);
    Transform* patch = createPatch(filename, poptions);
    BoundingSphere bsphere = patch->getBound();
    pgroup->setCenter(bsphere.center());
    if (poptions->getPatchLevel() >= _maxLevel)
    {
        pgroup->addChild(patch, 0.0, 1e10);
    }
    else
    {
        pgroup->addChild(patch, 0.0, 1.0);
        pgroup->setRange(1, 1.0, 1e10);
        pgroup->setFileName(1, "foo.osgearth_engine_seamless_patch");
    }
    return pgroup;
}
예제 #10
0
    bool sphereSphereCollision(const BoundingSphere &M,
                               const Vec3f &vel,
                               const BoundingSphere &S)
    {
        const Vec3f e = M.center() - S.center();
        const float r = S.radius() + M.radius();

        if ( vecLength(e) < r )
            return true;

        const float delta = Math::square(vecDot(e, vel))
            - vecDot(vel, vel) * (vecDot(e, e) - r*r);
        if ( delta < 0.0f )
            return false;

        const float t = (-vecDot(e, vel) - std::sqrt(delta)) / vecDot(vel, vel);
        if ( t < 0.0f || t > 1.0f )
            return false;

        return true;
    }
bool BasicPrimitiveTests::IntersectingRayAgainstSphere(const Ray & ray, const BoundingSphere & sphere, float & rtn_t)
{
	/*
		Main idea:
            - Ray is substituted into sphere equation. Then solve quadratic formula for intersection.
                - Test if intersection is within segment/ray endpoints

        -> Use dot(X-C, X-C) = exp(r, 2)
            -> As sphere equation.

        Solving for "t":
            -> Quadratic equation in "t" encountered.
                    -> where b = dot(m, d)
                    -> where c = dot(m, m) - r*r
						-> where m = P-C
                -> t = -b + sqrt(exp(b, 2) - c)
                -> t = -b - sqrt(exp(b, 2) - c)

        Notes:
            -> Number of real roots => number of intersections:
                -> Categorized by discriminant d = exp(b, 2) - c

            -> May have false intersection with t < 0 when ray starts from inside sphere.
	*/
	
	Eigen::Vector3f m = ray.GetOrigin() - sphere.GetCenter();
	float b = (m).dot(ray.GetDirection());
	float c = m.dot(m);
	if (c > 0.0f && b > 0.0f)
	{
		//Case: Ray origin outside of sphere and points away. => No Intersections.
		return false;
	}
	float discriminant = b * b - c;
	if (discriminant < 0.0f)
	{
		//Case: Misses sphere
		return false;
	}
	else
	{
		//Case: Hits sphere. Calculate smallest t.
		rtn_t = -b - sqrt(discriminant);
		if (rtn_t < 0.0f)
		{
			rtn_t = 0.0f;
		}
		return true;
	}
	
}
예제 #12
0
//----------------------------------------------------------------------------
bool Culler::IsVisible (BoundingSphere const& sphere)
{
    if (sphere.GetRadius() == 0.0f)
    {
        // The node is a dummy node and cannot be visible.
        return false;
    }

    // Start with the last pushed plane, which is potentially the most
    // restrictive plane.
    int index = mPlaneQuantity - 1;
    unsigned int mask = (1u << index);

    for (int i = 0; i < mPlaneQuantity; ++i, --index, mask >>= 1)
    {
        if (mPlaneState & mask)
        {
            int side = sphere.WhichSide(mPlane[index]);

            if (side < 0)
            {
                // The object is on the negative side of the plane, so
                // cull it.
                return false;
            }

            if (side > 0)
            {
                // The object is on the positive side of plane.  There is
                // no need to compare subobjects against this plane, so
                // mark it as inactive.
                mPlaneState &= ~mask;
            }
        }
    }

    return true;
}
예제 #13
0
    float sphereEdgeDistance(
        const BoundingSphere &sphere,
        const Vec3f &D,
        const Vec3f &A,
        const Vec3f &B,
        Vec3f *contactPoint)
    {
        const Vec3f AB = B - A;
        const Vec3f C = sphere.center() - A;
        const float AB2 = vecDot(AB, AB);
        const float AB_dot_C = vecDot(C, AB);
        const float AB_dot_D = vecDot(AB, D);

        float minR;
        if ( !Math::lowestPositiveQuadraticRoot(
                 vecDot(D, D) - Math::square(AB_dot_D)/AB2,
                 2.0f*(vecDot(C, D) - (AB_dot_D*AB_dot_C)/AB2),
                 vecDot(C, C) - Math::square(sphere.radius())
                 - Math::square(AB_dot_C)/AB2,
                 &minR) )
        {
            return NoIntersection;
        }

        const ud::Vec3f intersect = sphere.center() + D*minR - A; 
        const float t = vecDot(AB, intersect);
        if ( 0.0f <= t && t <= AB2 )
        {
            *contactPoint = A + AB * t;
            return minR;
        }
        else
        {
            return NoIntersection;
        }

    }
예제 #14
0
파일: plane.cpp 프로젝트: MrShedman/GL-Dev
IntersectData Plane::IntersectSphere(const BoundingSphere& other) const
{
	//Calculating the dot product between the Plane's normal and the Sphere's 
	//center gets how far the sphere's center is along the Plane's normal.
	//
	//Adding the distance adjusts this value based on how far the Plane itself
	//is along the normal.
	//
	//The end result of this is how far the Sphere's center is from the Plane.
	//The absolute value is taken so that this result is always positive.
	float distanceFromSphereCenter = 
		(float)fabs(m_normal.Dot(other.GetCenter()) + m_distance);

	//As long as the distanceFromSphereCenter is valid and positive, then
	//the distance from the sphere can be calculated simply by subtracting
	//it's radius.
	float distanceFromSphere = distanceFromSphereCenter - other.GetRadius();

	//The only time the plane can be intersecting the sphere is if the sphere
	//has less than 0 distance from the plane. Otherwise, if there is distance
	//between the plane and sphere, then there must be a gap between the
	//plane and sphere, and they cannot be intersecting.
	return IntersectData(distanceFromSphere < 0, m_normal * distanceFromSphere);
}
예제 #15
0
void BoundingSphere::expandBy(const BoundingSphere& sh)
{
    // ignore operation if incomming BoundingSphere is invalid.
    if (!sh.valid()) return;

    // This sphere is not set so use the inbound sphere
    if (!valid())
    {
        _center = sh._center;
        _radius = sh._radius;

        return;
    }
    
    
    // Calculate d == The distance between the sphere centers   
    double d = ( _center - sh.center() ).length();

    // New sphere is already inside this one
    if ( d + sh.radius() <= _radius )  
    {
        return;
    }

    //  New sphere completely contains this one 
    if ( d + _radius <= sh.radius() )  
    {
        _center = sh._center;
        _radius = sh._radius;
        return;
    }

    
    // Build a new sphere that completely contains the other two:
    //
    // The center point lies halfway along the line between the furthest
    // points on the edges of the two spheres.
    //
    // Computing those two points is ugly - so we'll use similar triangles
    double new_radius = (_radius + d + sh.radius() ) * 0.5;
    double ratio = ( new_radius - _radius ) / d ;

    _center[0] += ( sh.center()[0] - _center[0] ) * ratio;
    _center[1] += ( sh.center()[1] - _center[1] ) * ratio;
    _center[2] += ( sh.center()[2] - _center[2] ) * ratio;

    _radius = new_radius;

}
예제 #16
0
void BoundingSphere::expandRadiusBy(const BoundingSphere& sh)
{
    if (sh.valid())
    {
        if (valid())
        {
            value_type r = (sh._center-_center).length()+sh._radius;
            if (r>_radius) _radius = r;
            // else do nothing as vertex is within sphere.
        }
        else
        {
            _center = sh._center;
            _radius = sh._radius;
        }
    }
}
예제 #17
0
void BoundingSphere::merge(const BoundingSphere& sphere)
{
    if (sphere.isEmpty())
        return;

    // Calculate the distance between the two centers.
    float vx = center.x - sphere.center.x;
    float vy = center.y - sphere.center.y;
    float vz = center.z - sphere.center.z;
    float d = sqrt(vx * vx + vy * vy + vz * vz);

    // If one sphere is contained inside the other, set to the larger sphere.
    if (d <= (sphere.radius - radius))
    {
        center = sphere.center;
        radius = sphere.radius;
        return;
    }
    else if (d <= (radius - sphere.radius))
    {
        return;
    }

    // Calculate the unit vector between the two centers.
    GP_ASSERT(d != 0.0f);
    float dI = 1.0f / d;
    vx *= dI;
    vy *= dI;
    vz *= dI;

    // Calculate the new radius.
    float r = (radius + sphere.radius + d) * 0.5f;

    // Calculate the new center.
    float scaleFactor = (r - sphere.radius);
    vx = vx * scaleFactor + sphere.center.x;
    vy = vy * scaleFactor + sphere.center.y;
    vz = vz * scaleFactor + sphere.center.z;

    // Set the new center and radius.
    center.x = vx;
    center.y = vy;
    center.z = vz;
    radius = r;
}
예제 #18
0
bool RayIntersector::intersects(const BoundingSphere& bs)
{
    // if bs not valid then return false based on the assumption that the node is empty.
    if (!bs.valid()) return false;

    // test for _start inside the bounding sphere
    Vec3d sm = _start - bs._center;
    double c = sm.length2() - bs._radius * bs._radius;
    if (c<0.0) return true;

    // solve quadratic equation
    double a = _direction.length2();
    double b = (sm * _direction) * 2.0;
    double d = b * b - 4.0 * a * c;

    // no intersections if d<0
    if (d<0.0) return false;

    // compute two solutions of quadratic equation
    d = sqrt(d);
    double div = 1.0/(2.0*a);
    double r1 = (-b-d)*div;
    double r2 = (-b+d)*div;

    // return false if both intersections are before the ray start
    if (r1<=0.0 && r2<=0.0) return false;

    // if LIMIT_NEAREST and closest point of bounding sphere is further than already found intersection, return false
    if (_intersectionLimit == LIMIT_NEAREST && !getIntersections().empty())
    {
        double minDistance = sm.length() - bs._radius;
        if (minDistance >= getIntersections().begin()->distance) return false;
    }

    // passed all the rejection tests so line must intersect bounding sphere, return true.
    return true;
}
예제 #19
0
    float sphereTriangleCollision(
        const BoundingSphere &sphere,
        const Vec3f &dir,
        const Vec3f &p0, const Vec3f &p1,
        const Vec3f &p2, Vec3f *contactPoint)
    {
        Planef trigPlane(p0, p1, p2);
        float d = vecDot(dir, trigPlane.normal);
        float minDist = NoIntersection;

        if  ( vecDot(dir, trigPlane.normal) > 0.0 )
        {
            return NoIntersection;
        }
    
        if ( d == 0.0f )
        {
            if ( trigPlane.distance(sphere.center()) < sphere.radius() )
                return NoIntersection;
        }
        else 
        {
            const Vec3f orign = sphere.center()
                - sphere.radius()*vecNormal(trigPlane.normal);
            const float t = -(trigPlane.d + vecDot(orign, trigPlane.normal)) / d;

            if ( t >= 0.0f )
            {
            
                const Vec3f planePoint = orign + dir * t;
                if ( pointInTriangle(planePoint,
                                     vecNormal(trigPlane.normal),
                                     p0, p1, p2) )
                {
                    *contactPoint = planePoint;
                    return t;
                }
            }
        }

        float dist = spherePointDistance(sphere, dir, p0);
        if ( dist < minDist )
        {
            minDist = dist;
            *contactPoint = p0;
        }

        dist = spherePointDistance(sphere, dir, p1);
        if ( dist < minDist )
        {
            minDist = dist;
            *contactPoint = p1;
        }

        dist = spherePointDistance(sphere, dir, p2);
        if ( dist < minDist )
        {
            minDist = dist;
            *contactPoint = p2;
        }

        Vec3f edgeContactPoint;
        dist = sphereEdgeDistance(sphere, dir, p1, p0, &edgeContactPoint);
        if ( dist < minDist )
        {
            minDist = dist;
            *contactPoint = edgeContactPoint;
        }

        dist = sphereEdgeDistance(sphere, dir, p2, p1, &edgeContactPoint);
        if ( dist < minDist )
        {
            minDist = dist;
            *contactPoint = edgeContactPoint;
        }

        dist = sphereEdgeDistance(sphere, dir, p0, p2, &edgeContactPoint);
        if ( dist < minDist )
        {
            minDist = dist;
            *contactPoint = edgeContactPoint;
        }

        return minDist;
    }
예제 #20
0
파일: Pollen.cpp 프로젝트: marzer/Yggdrasil
	Pollen() noexcept
		: type((Type)Random<uint32_t>(0u,3u))
	{
		{
			Lock lock(mxCounter);
			if ((++counter) == 1)
			{			
				//create an icosphere of radius 1.0f
				std::vector<Vec3> spherePositions;
				{
					Mesh mesh;
					auto data(mesh.Sphere({}, 1.0f, YGG_DEBUG_CONDITIONAL(2,4), true).Decompose());
					for (auto i : data->Indices)
						spherePositions.push_back(data->Positions[i]);
				}

				//deform a copy of the sphere once for each type
				for (Type t = Type::Linear; t < Type::Count; t = (Type)((uint32_t)t + 1u))
				{
					uint32_t spikeCount(40);
					switch (t)
					{
						case Type::Linear: spikeCount = 3 * spikeCount / 4; break;
						case Type::Square: spikeCount = 2 * spikeCount / 3; break;
						case Type::Circular: spikeCount = spikeCount / 2; break;
					}

					//pick equidistant points around unit sphere (see http://www.cmu.edu/biolphys/deserno/pdf/sphere_equi.pdf)
					std::vector<Vec3> spikes;
					float a((4.0f * Pi) / (float)spikeCount);
					float d(sqrtf(a));
					uint32_t mTheta(Round<uint32_t>(Pi / d));
					float dTheta(Pi / (float)mTheta);
					float dAlpha(a / dTheta);
					for (uint32_t m = 0; m < mTheta; ++m)
					{
						float theta((Pi*((float)m + 0.5f)) / (float)mTheta);
						uint32_t mAlpha(Round<uint32_t>((2.0f * Pi * sinf(theta)) / dAlpha));
						for (uint32_t n = 0; n < mAlpha; ++n)
						{
							float alpha((2.0f * Pi * (float)n) / (float)mAlpha);
							spikes.emplace_back(sinf(theta) * cosf(alpha),
								sinf(theta)*sinf(alpha),
								cos(theta));
						}
					}

					//minimum distance to consider a spike as being "in range"
					float rad = d / 2.1f;

					//loop through the vertices and deform the sphere based 
					//on proximity to nearest spike
					std::vector<Vec3> positions(spherePositions);
					for (size_t v = 0; v < positions.size(); ++v)
					{
						//find closest spike
						float dist(Vec3::DistanceSquared(positions[v], spikes[0]));
						for (size_t s = 1; s < spikes.size(); ++s)
							dist = std::min(dist, Vec3::DistanceSquared(positions[v], spikes[s]));

						//convert distance into a proximity function & deform
						dist = ((rad - sqrtf(dist)) / rad);
						positions[v] *= metrics.Radius + metrics.Radius * 0.25f * ApplyDeformation(t, dist);

					}

					//create static mesh
					Mesh mesh;
					meshes.emplace_back(new StaticMesh(mesh.AddPositions(std::move(positions)).GenerateIndices().GenerateNormals()));
				}

			}
			if (Game::Physics()->Started() && !rigidBodyMesh)
				rigidBodyMesh = Game::Physics()->CreateSphereMesh(metrics.Radius);
		}


		entity.reset(Game::Scene()->Create("", this));
		auto _position(PickSpawnLocation(true));
		transform = entity->Add<Transform>(_position);
		transform->Forward(Random<Vec3>());
		static std::vector<Colour> colours
		{
			Yellow, Olive, BlanchedAlmond, YellowGreen
		};
		material.reset(new Phong(Colour(colours[Random<size_t>(0, colours.size() - 1)],0.0f)));
		entity->Add<MeshRenderer>(meshes[Random<size_t>(0, meshes.size() - 1)], material);

		if (Game::Physics()->Started())
			rigidBody.reset(Game::Physics()->Create(rigidBodyMesh, true, _position, transform->Orientation(), metrics.Density));
		entity->Add<Ticker>()->OnTick += [](Ticker* t, float deltaTime)
		{
			auto pollen(static_cast<Pollen*>(t->Entity()->Data));
			if (Game::Physics()->Started())
				pollen->transform->Pose(pollen->rigidBody->Position(), pollen->rigidBody->Orientation());

			if (!world.Contains(pollen->transform->Position()))
			{
				Vec3 newPos(PickSpawnLocation(false));
				pollen->transform->Position(newPos);
				if (Game::Physics()->Started())
					pollen->rigidBody->Position(newPos).Stop();
				pollen->spawnTime = 0.0f;
			}

			pollen->spawnTime += deltaTime;
			float alpha(std::min(pollen->spawnTime * 0.33f,1.0f));
			if (!spawnBounds.Contains(pollen->transform->Position()))
			{
				alpha = std::min(1.0f - Clamp((Vec3::Distance(spawnBounds.Center, pollen->transform->Position()) - spawnBounds.Radius)
					/ (world.Radius - spawnBounds.Radius), 0.0f, 1.0f), alpha);
			}
			pollen->material->Colour(Colour(pollen->material->Colour(), alpha));
		};
	}
예제 #21
0
파일: BoundingBox.cpp 프로젝트: jejatu/3d
bool BoundingBox::intersect(BoundingSphere& boundingSphere) {
    return boundingSphere.intersect(*this);
}
예제 #22
0
bool BoundingPolyhedron::intersects (BoundingSphere &bs) {
    return bs.intersects (*this);
}
예제 #23
0
bool Drone::SelectionTest(GLVector3f w)
{
    float distance = (mPosition - w).length();
    BoundingSphere* bSphere = (BoundingSphere*) mBoundingShape.GetPtr();
    return (distance <= bSphere->GetRadius());
}
예제 #24
0
TEST(BoundingSphere, Contains_BoundingBox)
{
    BoundingSphere sphere;
    sphere.Center = Vector3::Zero;
    sphere.Radius = 42.0f;

    auto min = Vector3::Normalize({-1.f, -1.f, -1.f}) * 42.0f;
    auto max = Vector3::Normalize({1.f, 1.f, 1.f}) * 42.0f;
    auto unit = Vector3::Normalize({1.f, 1.f, 1.f}) * 42.0f;

    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingBox{Vector3::Zero, max}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingBox{Vector3::Zero - unit * Vector3::UnitX, max - unit * Vector3::UnitX}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingBox{Vector3::Zero - unit * Vector3::UnitY, max - unit * Vector3::UnitY}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingBox{Vector3::Zero - unit * Vector3::UnitZ, max - unit * Vector3::UnitZ}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingBox{min, Vector3::Zero}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingBox{min + unit * Vector3::UnitX, Vector3::Zero + unit * Vector3::UnitX}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingBox{min + unit * Vector3::UnitY, Vector3::Zero + unit * Vector3::UnitY}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingBox{min + unit * Vector3::UnitZ, Vector3::Zero + unit * Vector3::UnitZ}));

    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingBox{Vector3::Zero, max * 1.01f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingBox{Vector3::Zero - unit * Vector3::UnitX, max * 1.01f - unit * Vector3::UnitX}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingBox{Vector3::Zero - unit * Vector3::UnitY, max * 1.01f - unit * Vector3::UnitY}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingBox{Vector3::Zero - unit * Vector3::UnitZ, max * 1.01f - unit * Vector3::UnitZ}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingBox{min * 1.01f, Vector3::Zero}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingBox{min * 1.01f + unit * Vector3::UnitX, Vector3::Zero + unit * Vector3::UnitX}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingBox{min * 1.01f + unit * Vector3::UnitY, Vector3::Zero + unit * Vector3::UnitY}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingBox{min * 1.01f + unit * Vector3::UnitZ, Vector3::Zero + unit * Vector3::UnitZ}));

    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(BoundingBox{max * 1.01f, max * 1.01f + unit}));
}
예제 #25
0
TEST(BoundingSphere, Contains_BoundingSphere)
{
    BoundingSphere sphere;
    sphere.Center = Vector3::Zero;
    sphere.Radius = 42.0f;

    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(sphere));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3::Zero, 43.0f}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingSphere{Vector3::Zero, 41.0f}));

    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingSphere{Vector3{40.f, 0.f, 0.f}, 1.9f}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingSphere{Vector3{0.f, 40.f, 0.f}, 1.9f}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingSphere{Vector3{0.f, 0.f, 40.f}, 1.9f}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingSphere{Vector3{-40.f, 0.f, 0.f}, 1.9f}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingSphere{Vector3{0.f, -40.f, 0.f}, 1.9f}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(BoundingSphere{Vector3{0.f, 0.f, -40.f}, 1.9f}));

    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{42.f, 0.f, 0.f}, 1.0f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{0.f, 42.f, 0.f}, 1.0f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{0.f, 0.f, 42.f}, 1.0f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{-42.f, 0.f, 0.f}, 1.0f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{0.f, -42.f, 0.f}, 1.0f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{0.f, 0.f, -42.f}, 1.0f}));

    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{43.f, 0.f, 0.f}, 2.0f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{0.f, 43.f, 0.f}, 2.0f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{0.f, 0.f, 43.f}, 2.0f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{-43.f, 0.f, 0.f}, 2.0f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{0.f, -43.f, 0.f}, 2.0f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(BoundingSphere{Vector3{0.f, 0.f, -43.f}, 2.0f}));

    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(BoundingSphere{Vector3{43.f, 0.f, 0.f}, 0.5f}));
    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(BoundingSphere{Vector3{0.f, 43.f, 0.f}, 0.5f}));
    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(BoundingSphere{Vector3{0.f, 0.f, 43.f}, 0.5f}));
    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(BoundingSphere{Vector3{-43.f, 0.f, 0.f}, 0.5f}));
    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(BoundingSphere{Vector3{0.f, -43.f, 0.f}, 0.5f}));
    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(BoundingSphere{Vector3{0.f, 0.f, -43.f}, 0.5f}));
}
예제 #26
0
TEST(BoundingSphere, Contains_Vector3)
{
    BoundingSphere sphere;
    sphere.Center = Vector3::Zero;
    sphere.Radius = 42.0f;

    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(Vector3::Zero));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(Vector3{41.f, 0.f, 0.f}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(Vector3{0.f, 41.f, 0.f}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(Vector3{0.f, 0.f, 41.f}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(Vector3{-41.f, 0.f, 0.f}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(Vector3{0.f, -41.f, 0.f}));
    EXPECT_EQ(ContainmentType::Contains, sphere.Contains(Vector3{0.f, 0.f, -41.f}));

    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(Vector3{42.f, 0.f, 0.f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(Vector3{0.f, 42.f, 0.f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(Vector3{0.f, 0.f, 42.f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(Vector3{-42.f, 0.f, 0.f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(Vector3{0.f, -42.f, 0.f}));
    EXPECT_EQ(ContainmentType::Intersects, sphere.Contains(Vector3{0.f, 0.f, -42.f}));

    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(Vector3{43.f, 0.f, 0.f}));
    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(Vector3{0.f, 43.f, 0.f}));
    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(Vector3{0.f, 0.f, 43.f}));
    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(Vector3{-43.f, 0.f, 0.f}));
    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(Vector3{0.f, -43.f, 0.f}));
    EXPECT_EQ(ContainmentType::Disjoint, sphere.Contains(Vector3{0.f, 0.f, -43.f}));
}
예제 #27
0
TEST(BoundingSphere, Intersects_BoundingSphere)
{
    BoundingSphere sphere;
    sphere.Center = Vector3::Zero;
    sphere.Radius = 42.0f;

    EXPECT_TRUE(sphere.Intersects(sphere));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3::Zero, 43.0f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3::Zero, 41.0f}));

    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{40.f, 0.f, 0.f}, 1.9f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, 40.f, 0.f}, 1.9f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, 0.f, 40.f}, 1.9f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{-40.f, 0.f, 0.f}, 1.9f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, -40.f, 0.f}, 1.9f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, 0.f, -40.f}, 1.9f}));

    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{42.f, 0.f, 0.f}, 1.0f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, 42.f, 0.f}, 1.0f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, 0.f, 42.f}, 1.0f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{-42.f, 0.f, 0.f}, 1.0f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, -42.f, 0.f}, 1.0f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, 0.f, -42.f}, 1.0f}));

    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{43.f, 0.f, 0.f}, 2.0f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, 43.f, 0.f}, 2.0f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, 0.f, 43.f}, 2.0f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{-43.f, 0.f, 0.f}, 2.0f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, -43.f, 0.f}, 2.0f}));
    EXPECT_TRUE(sphere.Intersects(BoundingSphere{Vector3{0.f, 0.f, -43.f}, 2.0f}));

    EXPECT_FALSE(sphere.Intersects(BoundingSphere{Vector3{43.f, 0.f, 0.f}, 0.5f}));
    EXPECT_FALSE(sphere.Intersects(BoundingSphere{Vector3{0.f, 43.f, 0.f}, 0.5f}));
    EXPECT_FALSE(sphere.Intersects(BoundingSphere{Vector3{0.f, 0.f, 43.f}, 0.5f}));
    EXPECT_FALSE(sphere.Intersects(BoundingSphere{Vector3{-43.f, 0.f, 0.f}, 0.5f}));
    EXPECT_FALSE(sphere.Intersects(BoundingSphere{Vector3{0.f, -43.f, 0.f}, 0.5f}));
    EXPECT_FALSE(sphere.Intersects(BoundingSphere{Vector3{0.f, 0.f, -43.f}, 0.5f}));
}
예제 #28
0
TEST(BoundingSphere, Intersects_BoundingBox)
{
    BoundingSphere sphere;
    sphere.Center = Vector3::Zero;
    sphere.Radius = 42.0f;

    auto min = Vector3::Normalize({-1.f, -1.f, -1.f}) * 42.0f;
    auto max = Vector3::Normalize({1.f, 1.f, 1.f}) * 42.0f;
    auto unit = Vector3::Normalize({1.f, 1.f, 1.f}) * 42.0f;

    EXPECT_TRUE(sphere.Intersects(BoundingBox{Vector3::Zero, max}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{Vector3::Zero - unit * Vector3::UnitX, max - unit * Vector3::UnitX}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{Vector3::Zero - unit * Vector3::UnitY, max - unit * Vector3::UnitY}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{Vector3::Zero - unit * Vector3::UnitZ, max - unit * Vector3::UnitZ}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{min, Vector3::Zero}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{min + unit * Vector3::UnitX, Vector3::Zero + unit * Vector3::UnitX}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{min + unit * Vector3::UnitY, Vector3::Zero + unit * Vector3::UnitY}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{min + unit * Vector3::UnitZ, Vector3::Zero + unit * Vector3::UnitZ}));

    EXPECT_TRUE(sphere.Intersects(BoundingBox{Vector3::Zero, max * 1.01f}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{Vector3::Zero - unit * Vector3::UnitX, max * 1.01f - unit * Vector3::UnitX}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{Vector3::Zero - unit * Vector3::UnitY, max * 1.01f - unit * Vector3::UnitY}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{Vector3::Zero - unit * Vector3::UnitZ, max * 1.01f - unit * Vector3::UnitZ}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{min * 1.01f, Vector3::Zero}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{min * 1.01f + unit * Vector3::UnitX, Vector3::Zero + unit * Vector3::UnitX}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{min * 1.01f + unit * Vector3::UnitY, Vector3::Zero + unit * Vector3::UnitY}));
    EXPECT_TRUE(sphere.Intersects(BoundingBox{min * 1.01f + unit * Vector3::UnitZ, Vector3::Zero + unit * Vector3::UnitZ}));

    EXPECT_FALSE(sphere.Intersects(BoundingBox{max * 1.01f, max * 1.01f + unit}));
}
예제 #29
0
bool BoundingBox::intersects(const BoundingSphere& sphere) const
{
    return sphere.intersects(*this);
}
예제 #30
0
파일: Ray.cpp 프로젝트: Swillis57/YAX
	std::unique_ptr<float> Ray::Intersects(const BoundingSphere& bs)
	{
		return bs.Intersects(*this);
	}