bool IntrLine3Box3<Real>::DoClipping ( Real t0, Real t1,
                                           const Vector3<Real>& origin, const Vector3<Real>& direction,
                                           const Box3<Real>& box, bool solid, int& quantity, Vector3<Real> point[2],
                                           int& intrType )
    {
        // Convert linear component to box coordinates.
        Vector3<Real> diff = origin - box.Center;
        Vector3<Real> BOrigin(
            diff.Dot( box.Axis[0] ),
            diff.Dot( box.Axis[1] ),
            diff.Dot( box.Axis[2] )
        );
        Vector3<Real> BDirection(
            direction.Dot( box.Axis[0] ),
            direction.Dot( box.Axis[1] ),
            direction.Dot( box.Axis[2] )
        );

        Real saveT0 = t0, saveT1 = t1;
        bool notAllClipped =
            Clip( +BDirection.X(), -BOrigin.X() - box.Extent[0], t0, t1 ) &&
            Clip( -BDirection.X(), +BOrigin.X() - box.Extent[0], t0, t1 ) &&
            Clip( +BDirection.Y(), -BOrigin.Y() - box.Extent[1], t0, t1 ) &&
            Clip( -BDirection.Y(), +BOrigin.Y() - box.Extent[1], t0, t1 ) &&
            Clip( +BDirection.Z(), -BOrigin.Z() - box.Extent[2], t0, t1 ) &&
            Clip( -BDirection.Z(), +BOrigin.Z() - box.Extent[2], t0, t1 );

        if ( notAllClipped && ( solid || t0 != saveT0 || t1 != saveT1 ) )
        {
            if ( t1 > t0 )
            {
                intrType = IT_SEGMENT;
                quantity = 2;
                point[0] = origin + t0 * direction;
                point[1] = origin + t1 * direction;
            }
            else
            {
                intrType = IT_POINT;
                quantity = 1;
                point[0] = origin + t0 * direction;
            }
        }
        else
        {
            quantity = 0;
            intrType = IT_EMPTY;
        }

        return intrType != IT_EMPTY;
    }
	Bool  HawkLine3D::Intersect(const HawkOBB& oBox,Vec3IntrResult* pResult) const
	{
		const HawkVector3D* Axis = oBox.GetAxis();
		HawkVector3D diff        = Point - oBox.Center;
		HawkVector3D BOrigin(
			diff.DotProduct(Axis[0]),
			diff.DotProduct(Axis[1]),
			diff.DotProduct(Axis[2])
			);
		HawkVector3D BDirection(
			Direction.DotProduct(Axis[0]),
			Direction.DotProduct(Axis[1]),
			Direction.DotProduct(Axis[2])
			);

		Float t0 = -FLT_MAX,t1 = FLT_MAX;
		bool notAllClipped =
			geoClip(+BDirection.X, -BOrigin.X-oBox.Extent[0], t0, t1) &&
			geoClip(-BDirection.X, +BOrigin.X-oBox.Extent[0], t0, t1) &&
			geoClip(+BDirection.Y, -BOrigin.Y-oBox.Extent[1], t0, t1) &&
			geoClip(-BDirection.Y, +BOrigin.Y-oBox.Extent[1], t0, t1) &&
			geoClip(+BDirection.Z, -BOrigin.Z-oBox.Extent[2], t0, t1) &&
			geoClip(-BDirection.Z, +BOrigin.Z-oBox.Extent[2], t0, t1);

		if (notAllClipped)
		{
			//2交点
			if (t1 > t0)
			{
				if (pResult)
				{
					pResult->Factor = HawkMath::Abs<Float>(t0) < HawkMath::Abs<Float>(t1)? t0 : t1;
					pResult->Point  = Point + Direction * pResult->Factor;
				}
				return true;
			}
			//1交点
			else
			{
				if (pResult)
				{
					pResult->Factor = t0;
					pResult->Point  = Point + Direction * pResult->Factor;
				}
				return true;
			}
		}
		return false;
	}
Beispiel #3
0
    /**
     * @brief intersect a geometric object.
     * @param ray_ the ray
     * @param p_diff_geom_ the result of the intersection
     * @return true if the ray intersects the geometry. Modifies the ray_.max_t() value, intersect only if the intersection
     * is before ray_.max_t()
     * @todo Factorize code shared by Box3D::clip()
     *
     * Adapted from http://www.geometrictools.com/LibMathematics/Intersection/Wm5IntrLine3Box3.cpp
     */
    bool intersect (Ray& ray_, Diff_Geom * p_diff_geom_) const {
        float t0 = -ray_.ray_epsilon();
        float t1 = ray_.max_t();

        // Convert linear component to box coordinates.
        Vector3D diff = ray_.ori() - m_center;
        Vector3D BOrigin(
            diff.dot(m_axis[0]),
            diff.dot(m_axis[1]),
            diff.dot(m_axis[2])
        );
        Vector3D BDirection(
            ray_.dir().dot(m_axis[0]),
            ray_.dir().dot(m_axis[1]),
            ray_.dir().dot(m_axis[2])
        );

        float saveT0 = t0, saveT1 = t1;
        bool notAllClipped;
        unsigned char updated;
        int nt0, nt1;
        notAllClipped = clip(+BDirection.x(), -BOrigin.x()-m_extent[0], t0, t1, updated);
        if (updated == 1)
            nt0 = 0;
        else if (updated == 2)
            nt1 = 0;
        notAllClipped = notAllClipped && clip(-BDirection.x(), +BOrigin.x()-m_extent[0], t0, t1, updated);
        if (updated == 1)
            nt0 = 1;
        else if (updated == 2)
            nt1 = 1;
        notAllClipped = notAllClipped && clip(+BDirection.y(), -BOrigin.y()-m_extent[1], t0, t1, updated);
        if (updated == 1)
            nt0 = 2;
        else if (updated == 2)
            nt1 = 2;
        notAllClipped = notAllClipped && clip(-BDirection.y(), +BOrigin.y()-m_extent[1], t0, t1, updated);
        if (updated == 1)
            nt0 = 3;
        else if (updated == 2)
            nt1 = 3;
        notAllClipped = notAllClipped && clip(+BDirection.z(), -BOrigin.z()-m_extent[2], t0, t1, updated);
        if (updated == 1)
            nt0 = 4;
        else if (updated == 2)
            nt1 = 4;
        notAllClipped = notAllClipped && clip(-BDirection.z(), +BOrigin.z()-m_extent[2], t0, t1, updated);
        if (updated == 1)
            nt0 = 5;
        else if (updated == 2)
            nt1 = 5;


        if (notAllClipped && (t0 != saveT0 || t1 != saveT1)) {

             if ( (t0 > ray_.ray_epsilon() ) && (t0 < ray_.max_t()) ){
                Vector3D normal = m_axis[nt0/2];
                if (nt0%2)
                    normal = -normal;
                p_diff_geom_->set_pos(ray_.at(t0));
                p_diff_geom_->set_normal(normal);
                p_diff_geom_->set_t(t0);
                ray_.set_max_t(t0);
                return true;
            } else if ( (t1 > ray_.ray_epsilon()) && (t1 < ray_.max_t()) ){
                 Vector3D normal = m_axis[nt1/2];
                 if (nt1%2)
                     normal = -normal;
                 p_diff_geom_->set_pos(ray_.at(t1));
                 p_diff_geom_->set_normal(normal);
                 p_diff_geom_->set_t(t1);
                 ray_.set_max_t(t1);
                 return true;
             } else
                return false;
        } else {
            return false;
        }
    }
Beispiel #4
0
    /**
     * @brief clip a ray by a Box3D.
     * @param ray_ the ray to clip
     * @param bounds ray sorted bounds of the resulting clipping segment.
     * @return  true if ray was clipped. bounds parameter is filld by this method
     *
     * For simple convex objects, there is two values in  bounds that represent in and out events.
     * An in event is whe the ray enters the geometry, an out is when the ray leaves the geometry.
     *
     * @todo Factorize code shared by Box3D::intersect()
     *
     * Adapted from http://www.geometrictools.com/LibMathematics/Intersection/Wm5IntrLine3Box3.cpp
     *
     */
    bool clip(Ray& ray_, IntervalSet &bounds) const {
        float t0 = std::numeric_limits<float>::min();
        float t1 = std::numeric_limits<float>::max();

        // Convert linear component to box coordinates.
        Vector3D diff = ray_.ori() - m_center;
        Vector3D BOrigin(
            diff.dot(m_axis[0]),
            diff.dot(m_axis[1]),
            diff.dot(m_axis[2])
        );
        Vector3D BDirection(
            ray_.dir().dot(m_axis[0]),
            ray_.dir().dot(m_axis[1]),
            ray_.dir().dot(m_axis[2])
        );

        float saveT0 = t0, saveT1 = t1;
        bool notAllClipped;
        unsigned char updated;
        int nt0, nt1;
        notAllClipped = clip(+BDirection.x(), -BOrigin.x()-m_extent[0], t0, t1, updated);
        if (updated == 1)
            nt0 = 0;
        else if (updated == 2)
            nt1 = 0;
        notAllClipped = notAllClipped && clip(-BDirection.x(), +BOrigin.x()-m_extent[0], t0, t1, updated);
        if (updated == 1)
            nt0 = 1;
        else if (updated == 2)
            nt1 = 1;
        notAllClipped = notAllClipped && clip(+BDirection.y(), -BOrigin.y()-m_extent[1], t0, t1, updated);
        if (updated == 1)
            nt0 = 2;
        else if (updated == 2)
            nt1 = 2;
        notAllClipped = notAllClipped && clip(-BDirection.y(), +BOrigin.y()-m_extent[1], t0, t1, updated);
        if (updated == 1)
            nt0 = 3;
        else if (updated == 2)
            nt1 = 3;
        notAllClipped = notAllClipped && clip(+BDirection.z(), -BOrigin.z()-m_extent[2], t0, t1, updated);
        if (updated == 1)
            nt0 = 4;
        else if (updated == 2)
            nt1 = 4;
        notAllClipped = notAllClipped && clip(-BDirection.z(), +BOrigin.z()-m_extent[2], t0, t1, updated);
        if (updated == 1)
            nt0 = 5;
        else if (updated == 2)
            nt1 = 5;

        if (notAllClipped && (t0 != saveT0 || t1 != saveT1)) {
            if (t1 > t0) {

                Vector3D normal = m_axis[nt0/2];
                if (nt0%2)
                    normal = -normal;
                Diff_Geom *in = new Diff_Geom(ray_.at(t0), normal, t0);

                normal = m_axis[nt1/2];
                if (nt1%2)
                    normal = -normal;
                Diff_Geom *out = new Diff_Geom(ray_.at(t1), normal, t1);
                bounds.add(in, out);
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }