void DisarmTrapSpell::Launch()
{
	ARX_SOUND_PlaySFX(SND_SPELL_DISARM_TRAP);
	
	m_duration = 1;
	
	Sphere sphere;
	sphere.origin = player.pos;
	sphere.radius = 400.f;
	
	for(size_t n = 0; n < MAX_SPELLS; n++) {
		SpellBase * spell = spells[SpellHandle(n)];
		
		if(!spell || spell->m_type != SPELL_RUNE_OF_GUARDING) {
			continue;
		}
		
		Vec3f pos = static_cast<RuneOfGuardingSpell *>(spell)->getPosition();
		
		if(sphere.contains(pos)) {
			spell->m_level -= m_level;
			if(spell->m_level <= 0) {
				spells.endSpell(spell);
			}
		}
	}
}
Example #2
0
bool AABB::intersectsSphere( const Sphere& s ) const
{
  // get the closest pt on the box to the sphere.
  Vector3f boxPt = s.c ;
  boxPt.clampComponent( min, max ) ;
  
  // see if the pt on the box is inside the sphere
  return s.contains( boxPt ) ;
}
Example #3
0
void testGLight() {
    GLight L = GLight::point(Vector3(1,2,3), Color3::white(), 1,0,0);
    Sphere s;
    
    s = L.effectSphere();
    debugAssert(s.contains(Vector3(1,2,3)));
    debugAssert(s.contains(Vector3(0,0,0)));
    debugAssert(s.contains(Vector3(100,100,100)));

    {
        GLight L = GLight::point(Vector3(1,2,3), Color3::white(), 1,0,1);
        Sphere s;
        
        s = L.effectSphere();
        debugAssert(s.contains(Vector3(1,2,3)));
        debugAssert(s.contains(Vector3(1,1,3)));
        debugAssert(! s.contains(Vector3(100,100,100)));
    }
}
Example #4
0
bool Cone::intersects(const Sphere& b) const {
    // If the bounding sphere contains the tip, then
    // they definitely touch.
    if (b.contains(this->tip)) {
        return true;
    }

    // Move the tip backwards, effectively making the cone bigger
    // to account for the radius of the sphere.

    Vector3 tip = this->tip - direction * b.radius / sinf(angle);

    return Cone(tip, direction, angle).contains(b.center);
}
Example #5
0
void Sphere::merge(const Sphere& other) {
    if (other.contains(*this)) {
        *this = other;
    } else if (! contains(other)) {
        // The farthest distance is along the axis between the centers, which
        // must not be colocated since neither contains the other.
        Vector3 toMe = center - other.center;
        // Get a point on the axis from each
        toMe = toMe.direction();
        const Vector3& A = center + toMe * radius;
        const Vector3& B = other.center - toMe * other.radius;

        // Now just bound the A->B segment
        center = (A + B) * 0.5f;
        radius = (A - B).length();
    }
    // (if this contains other, we're done)
}
Example #6
0
void testSphere() {
    printf("Sphere...");
    Sphere a(Vector3(0,3,0), 2);
    Sphere b(Vector3(0,2,0), 0.5f);

    debugAssert(a.contains(b));
    debugAssert(! b.contains(a));

    Sphere s = a;
    s.merge(b);
    debugAssert(s == a);

    Sphere c(Vector3(1,0,0), 2);
    s = a;
    s.merge(c);
    debugAssert(s.contains(a));
    debugAssert(s.contains(c));

    printf("passed\n");
}
bool HoverPlaneHelper::findMinimumHoverPlane (const Object & obj, float & roll, float & pitch, const Vector & lookAhead)
{
	Object const * motor = obj.getParent ();

	if(motor)
	{
		CollisionProperty const * collision = motor->getCollisionProperty();

		if(collision)
		{
			Footprint const * foot = collision->getFootprint();

			if(foot && foot->isOnSolidFloor())
			{
				Vector const & groundNormal_w = foot->getGroundNormal_w();

				const Transform & transform_o2w = obj.getTransform_o2w ();

				computeRollPitch (transform_o2w.rotate_p2l (groundNormal_w), roll, pitch);

				return true;
			}
		}
	}

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

	const Appearance * const app = obj.getAppearance ();
	if (!app)
		return false;

	const BoxExtent * const box = dynamic_cast<const BoxExtent *>(app->getExtent ());
	if (!box)
		return false;
	
	const Transform & transform_o2w = obj.getTransform_o2w ();

	Vector points [10];
	if (!transformBoxPoints (*box, transform_o2w, points, lookAhead))
		return false;

	const TerrainObject * const terrainObject = TerrainObject::getInstance ();

	if (!terrainObject)
		return false;

	Vector normals [10];
	Vector avgNormal;

	Vector avgLookAhead;
	int lookAheadContribCount = 0;

	Sphere s = box->getSphere ();
	s.setCenter (transform_o2w.getPosition_p ());
	float avgDistanceAboveTerrain = 0.0f;
	float minDistanceAboveTerrain = 10000.0f;

	//- find terrain heights for points
	{
		const Vector oldCenterPoint = points [0];

		float y = 0.0f;
		for (int i = 0; i < 10; ++i)
		{
			if (terrainObject->getHeight (points [i], y, normals [i]))
			{
				float waterHeight = 0.0f;
				const bool isWater = terrainObject->getWaterHeight (points[i], waterHeight);
				if(isWater && waterHeight > y)
				{
					normals[i] = Vector::unitY;
					y = waterHeight;
				}

				if (i >= 5)
				{
					//-- lookahead point is not in the sphere, let it contribute to the lookahead normal
					if (!s.contains (points [i]))
					{
						points [i].y = y;
						avgLookAhead += points [i] - oldCenterPoint;
						++lookAheadContribCount;
					}
					points [i].y = y;
				}
				else
				{
					const float distanceAbove = points [i].y - y;
					avgDistanceAboveTerrain += distanceAbove;
					minDistanceAboveTerrain = std::max (0.0f, std::min (minDistanceAboveTerrain, distanceAbove));
					points [i].y = y;
					avgNormal += normals [i];
				}
			}
			else
				return false;
		}
	}

	avgNormal /= 5.0f;
	avgDistanceAboveTerrain /= 5.0f;

	computeRollPitch (transform_o2w.rotate_p2l (avgNormal), roll, pitch);
	
	//-- decrease the roll & pitch based on height over terrain
	//--

	const float extentRadius = s.getRadius ();

	avgDistanceAboveTerrain -= extentRadius;

	if (avgDistanceAboveTerrain > 0.0f)
	{
		if (extentRadius > 0.0f)
		{
			const float relativeDistance = 1.0f + (avgDistanceAboveTerrain / (extentRadius  * 0.5f));
			roll /= relativeDistance;
			pitch /= relativeDistance;
		}
	}

	if (lookAheadContribCount)
	{
		avgLookAhead  /= static_cast<float>(lookAheadContribCount);

		Vector vectorToLookAhead = transform_o2w.rotate_p2l (avgLookAhead);

		float pitchLookAhead = 0.0f;

		if (vectorToLookAhead.normalize ())
			pitchLookAhead = vectorToLookAhead.phi ();
		else
			pitchLookAhead = 0.0f;

		if (pitchLookAhead < pitch)
		{
			pitch = pitchLookAhead;
		}
	}

	return true;
}
Example #8
0
Radiance3 RayTracer::L_indirectDiffuse
(const shared_ptr<Surfel>& surfel,
 const Vector3&            wo,
 ThreadData&               threadData) const {

    if (! surfel->nonZeroFiniteScattering() || (m_photonMap.size() == 0)) {
        // Either no scattering or no photons; don't bother computing
        return Radiance3::zero();
    }

    const Point3& X = surfel->position;

    Radiance3 L;
    const Sphere gatherSphere(X, m_settings.photon.maxGatherRadius);

    // Extract local triangles for collision detection
    Array<Tri>& localTris = threadData.localTri;
    if (m_settings.checkFinalVisibility && (gatherSphere.radius >= MIN_SURFACE_THICKNESS)) {
        getNearbyTris(surfel->position, surfel->geometricNormal, gatherSphere, localTris);
    }

    // Use the tri tree if there are too many elements in the array
    const bool useTriTreeVisibility = (localTris.size() > 10);

    for (PhotonMap::SphereIterator photon =
                m_photonMap.begin(gatherSphere);
            photon.isValid();
            ++photon) {
        debugAssert(gatherSphere.contains(photon->position));

        const Point3&  Y = photon->position;

        // Distance to the photon; affects falloff
        const float    s = (Y - X).length();

        // Radius of the photon's effect
        const float    r = photon->effectRadius;

        if (s < r) {
            // The falloff (smoothing) kernel will be non-zero.

            const Vector3&    wi = photon->wi;
            const Color3&     f  = surfel->finiteScatteringDensity(wi, wo);

            // Maybe check visibility; don't bother if there is no illumination
            if (m_settings.checkFinalVisibility && f.nonZero() && (s > MIN_SURFACE_THICKNESS)) {
                // The photon is an appreciable distance from the shading point.
                // Cast a visibility ray to ensure that it is actually a good estimator
                // of flux at this location and not, for example, on the other side
                // of a partition.  We should ideally be casting the ray back to the source
                // of the photon, but that information is no longer available.
                // Note that this code is similar to a VPL shadow ray or final gather ray.
                // Unlike VPLs, we already have a measure of visibility from the light source (and have
                // enough photons to make shading robust to moving objects)...and the ray cast
                // is always over a fairly short distance and thus likely to be fast.
                // Offset far enough that curved surfaces don't occlude themselves.
                const Vector3& offset = surfel->geometricNormal * (s * 0.5f + BUMP_EPSILON);

                const bool isVisible =
                    useTriTreeVisibility ?
                    visible(Y, X + offset) :
                    ::visible(Y, X + offset, localTris, m_triTree.cpuVertexArray());

                if (! isVisible) {
                    // Stop processing this photon's contribution to the surfel
                    continue;
                }
            }

            const Biradiance3& B = photon->power * clampedConeFalloff((X - Y).length(), 1.0f / r) / clampedConeVolume(r);

            L += B * f;
        }
    }

    return L;
}