コード例 #1
0
ファイル: cone.hpp プロジェクト: Chinmay-at-git/M1UPS
    /**
     * @brief clip a ray by a Cone.
     * @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.
     *
     * Adapted from http://www.geometrictools.com/LibMathematics/Intersection/Wm5IntrLine3Cone3.cpp
     *
     */
    bool clip(Ray& ray_, IntervalSet &bounds) const {
        Diff_Geom ipoints[2];
        float t[2];

        int numintersection = get_clip_points(ray_, ipoints,  t);
        if (numintersection == 0)
            return false;
        else if (numintersection == 2) {
            Diff_Geom *in = new Diff_Geom(ipoints[0].pos(), ipoints[0].normal(), t[0]);
            Diff_Geom *out = new Diff_Geom(ipoints[1].pos(), ipoints[1].normal(), t[1]);
            bounds.add(in, out);
            return true;
        } else {
            Diff_Geom *in, *out;
            IntervalSet capset;
            // check with cap plane
            Plane cap(m_vertex + m_axis * m_height, m_axis);
            if (cap.clip(ray_, capset) ) {
				/* Beuark mais ca facilite la gestion mémoire ... */
                Diff_Geom *tmp =capset.bounds()[0].data;
				in = new Diff_Geom(*tmp);
                if (in->t()< t[0]) {
                    out = new Diff_Geom(ipoints[0].pos(), ipoints[0].normal(), t[0]);
                } else {
                    out = in;
                    in = new Diff_Geom(ipoints[0].pos(), ipoints[0].normal(), t[0]);
                }

                bounds.add(in, out);
                return true;
            } else {
                return false;
            }
        }
    }
コード例 #2
0
ファイル: cone.hpp プロジェクト: Chinmay-at-git/M1UPS
    bool clip(Ray& ray_, IntervalSet &bounds) const {
        Diff_Geom ipoints[2];
        float t[2];

        int numintersection = get_clip_points(ray_, ipoints,  t);
        if (numintersection == 0)
            return false;
        else if (numintersection == 2) {
            Diff_Geom *in = new Diff_Geom(ipoints[0].pos(), ipoints[0].normal(), ipoints[0].dNdx(), ipoints[0].dNdy(), t[0], ipoints[0].dPdx(), ipoints[0].dPdy(), ipoints[0].dDdx(), ipoints[0].dDdy(), ipoints[0].u(), ipoints[0].v(), ipoints[0].dTdx(), ipoints[0].dTdy(), true);
            Diff_Geom *out = new Diff_Geom(ipoints[1].pos(), ipoints[1].normal(), ipoints[1].dNdx(), ipoints[1].dNdy(), t[1], ipoints[1].dPdx(), ipoints[1].dPdy(), ipoints[1].dDdx(), ipoints[1].dDdy(), ipoints[1].u(), ipoints[1].v(), ipoints[1].dTdx(), ipoints[1].dTdy(), false);
            bounds.add(in, out);
            return true;
        } else {
            Diff_Geom *in, *out;
            IntervalSet capset;
            // check with cap plane
            Plane cap(m_vertex + m_axis * m_height, m_axis);
            if (cap.clip(ray_, capset) ) {
                in = capset.bounds()[0].data;
                in->set_u(in->u()/(PSCALE*m_radius));
                in->set_v(in->v()/(PSCALE*m_radius));
                in->set_dTdx(in->dTdx()* (1.f/(PSCALE*m_radius)));
                in->set_dTdy(in->dTdy()* (1.f/(PSCALE*m_radius)));
                if (in->t()< t[0]) {
                //if (p_diff_geom_in_->t() < t[0]) {
                    out = new Diff_Geom(ipoints[0].pos(), ipoints[0].normal(), ipoints[0].dNdx(), ipoints[0].dNdy(), t[0], ipoints[0].dPdx(), ipoints[0].dPdy(), ipoints[0].dDdx(), ipoints[0].dDdy(), ipoints[0].u(), ipoints[0].v(), ipoints[0].dTdx(), ipoints[0].dTdy(), false);
                } else {
                    out = in;
                    out->set_in(false);
                    in = new Diff_Geom(ipoints[0].pos(), ipoints[0].normal(), ipoints[0].dNdx(), ipoints[0].dNdy(), t[0], ipoints[0].dPdx(), ipoints[0].dPdy(), ipoints[0].dDdx(), ipoints[0].dDdy(), ipoints[0].u(), ipoints[0].v(), ipoints[0].dTdx(), ipoints[0].dTdy(), true);
                }
                delete (capset.bounds()[1].data);
                bounds.add(in, out);
                return true;
            } else {
                return false;
            }
        }
    }
コード例 #3
0
ファイル: cone.hpp プロジェクト: Chinmay-at-git/M1UPS
    int get_clip_points(Ray& ray_, Diff_Geom ipoints[2], float t[2]) const{
        int numintersection = 0;
        Vector3D E = ray_.ori() - m_vertex;
        float AdD = m_axis.dot(ray_.dir());
        float cosSqr = m_costheta*m_costheta;
        float AdE = m_axis.dot(E);
        float DdE = ray_.dir().dot(E);
        float EdE = E.dot(E);
        float c2 = AdD*AdD-cosSqr;
        float c1 = AdD*AdE - cosSqr*DdE;
        float c0 = AdE*AdE - cosSqr*EdE;
        float dot;
        Vector3D zero;

        if (std::fabs(c2)>0) {
            float discr = c1*c1 - c0*c2;
            float invC2 = 1.f/c2;
            if (discr < 0) {
                // No intersection
                return  0;
            } else if (discr > 0) {
                // two distinct intersections
                float root = std::sqrt(discr);
                // entry point
                t[numintersection] = (-c1 + root) * invC2;
                E = ray_.at(t[numintersection]) - m_vertex;
                dot = E.dot(m_axis);
                if ( (dot > 0) && (dot <= m_height))
                {
                    fillConicalDiffGeom(ipoints[numintersection], ray_, t[numintersection], true);
                    ++numintersection;
                }
                // exit point
                t[numintersection] = (-c1 - root) * invC2;
                E = ray_.at(t[numintersection]) - m_vertex;
                dot = E.dot(m_axis);
                if ( (dot > 0)  && (dot <= m_height))
                {
                    fillConicalDiffGeom(ipoints[numintersection], ray_, t[numintersection], false);
                    ++numintersection;
                }
                return numintersection;
          } else {
                // one reapeated intersection : ray is tangent to the cone
                // may be return 0 instead of an intersection ?
                return 0;
                t[numintersection] = -c1 * invC2;
                E = ray_.at(t[numintersection]) - m_vertex;
                dot = E.dot(m_axis);
                if ( (dot > 0) && (dot <= m_height)) {
                    fillConicalDiffGeom(ipoints[numintersection], ray_, t[numintersection], true);
                    ++numintersection;
                }
                return numintersection;
           }
        } else if (std::fabs(c1) > 0) {
            // the ray is on the boundary of the cone
            // we consider no intersection
            // TODO : check this for CSG
            return 0;
        } else {
            //return false;
            // Cone contains ray V+tD
            // The ray intersect the cone exactly at its vertex :(
            // TODO : manage this particular case in another function
            ipoints[numintersection].set_pos(m_vertex);
            ipoints[numintersection].set_normal(-m_axis);

            ipoints[numintersection].set_u(1.f);
            ipoints[numintersection].set_v(0.f);

            E = ray_.ori() - m_vertex;
            t[numintersection] = ( (E.dot(ray_.dir())<0) ? std::sqrt(EdE) : -std::sqrt(EdE) ) ;
            ipoints[numintersection].set_t(t[numintersection]);
            ipoints[numintersection].set_in(true);
            ipoints[numintersection].set_u(0.f);
            ipoints[numintersection].set_v(1.f);

            // todo : compute here normal derivatives (according to x and y directions on the image plane)
            ipoints[numintersection].set_dNdx(zero);
            ipoints[numintersection].set_dNdy(zero);

            ++numintersection;
             // check with cap plane
            Plane cap(m_vertex + m_axis * m_height, m_axis);
            IntervalSet capset;
            if (cap.clip(ray_, capset)) {
                if (capset.bounds()[0].t < t[numintersection-1]) {
                    t[numintersection] = t[numintersection-1];
                    ipoints[numintersection] = ipoints[numintersection-1];
                    --numintersection;
                } else {
                    capset.bounds()[0].data->set_in(false);
                }
                ipoints[numintersection] = *(capset.bounds()[0].data);
                // TODO : update u, v dTdx and dTdy
                ipoints[numintersection].set_u(ipoints[numintersection].u()/(PSCALE*m_radius));
                ipoints[numintersection].set_v(ipoints[numintersection].v()/(PSCALE*m_radius));
                ipoints[numintersection].set_dTdx(ipoints[numintersection].dTdx()* (1.f/(PSCALE*m_radius)));
                ipoints[numintersection].set_dTdy(ipoints[numintersection].dTdy()* (1.f/(PSCALE*m_radius)));
                delete capset.bounds()[0].data;
                delete capset.bounds()[1].data;
                return 2;
            } else {
                // must never reach this point !
                assert(false);
                return 0;
            }
        }
    }
コード例 #4
0
ファイル: cone.hpp プロジェクト: Chinmay-at-git/M1UPS
    /**
     * @brief get_clip_points
     * @param ray_
     * @param ipoints
     * @param t
     * @return the number of clipping position on the ray (0 to 2)
     */
    int get_clip_points(Ray& ray_, Diff_Geom ipoints[2], float t[2]) const{
        int numintersection = 0;
        Vector3D E = ray_.ori() - m_vertex;
        float AdD = m_axis.dot(ray_.dir());
        float cosSqr = m_costheta*m_costheta;
        float AdE = m_axis.dot(E);
        float DdE = ray_.dir().dot(E);
        float EdE = E.dot(E);
        float c2 = AdD*AdD-cosSqr;
        float c1 = AdD*AdE - cosSqr*DdE;
        float c0 = AdE*AdE - cosSqr*EdE;
        float dot;
        if (std::fabs(c2)>0) {
            float discr = c1*c1 - c0*c2;
            float invC2 = 1.f/c2;
            if (discr < 0) {
                // No intersection
                return  0;
            } else if (discr > 0) {
                // two distinct intersections
                float root = std::sqrt(discr);
                // entry point
                t[numintersection] = (-c1 + root) * invC2;
                ipoints[numintersection].set_pos(ray_.at(t[numintersection]));
                E = ipoints[numintersection].pos() - m_vertex;
                dot = E.dot(m_axis);
                if ( (dot > 0) && (dot <= m_height))
                {
                    Vector3D normal=compute_normal(ipoints[numintersection].pos());
                    ipoints[numintersection].set_normal(normal);
                    ipoints[numintersection].set_t(t[numintersection]);
                    ++numintersection;
                }

                // exit point
                t[numintersection] = (-c1 - root) * invC2;
                ipoints[numintersection].set_pos(ray_.at(t[numintersection]));
                E = ipoints[numintersection].pos() - m_vertex;
                dot = E.dot(m_axis);
                if ( (dot > 0)  && (dot <= m_height))
                {
                    Vector3D normal=compute_normal(ipoints[numintersection].pos());
                    ipoints[numintersection].set_normal(normal);
                    ipoints[numintersection].set_t(t[numintersection]);
                    ++numintersection;
                }

                return numintersection;
          } else {
                // one reapeated intersection : ray is tangent to the cone
                // may be return 0 instead of an intersection ?
                return 0;
                t[numintersection] = -c1 * invC2;
                ipoints[numintersection].set_pos(ray_.at(t[numintersection]));
                E = ipoints[numintersection].pos() - m_vertex;
                dot = E.dot(m_axis);
                if ( (dot > 0) && (dot <= m_height)) {
                    Vector3D normal=compute_normal(ipoints[numintersection].pos());
                    ipoints[numintersection].set_normal(normal);
                    ipoints[numintersection].set_t(t[numintersection]);
                    ++numintersection;
                }
                return numintersection;
           }
        } else if (std::fabs(c1) > 0) {
            // the ray is on the boundary of the cone
            // we consider no intersection
            // TODO : check this for CSG
            return 0;
        } else {
            //return false;
            // Cone contains ray V+tD
            // The ray intersect the cone exactly at its vertex :(
            ipoints[numintersection].set_pos(m_vertex);
            ipoints[numintersection].set_normal(-m_axis);
            E = ray_.ori() - m_vertex;
            t[numintersection] = ( (E.dot(ray_.dir())<0) ? std::sqrt(EdE) : -std::sqrt(EdE) ) ;
            ipoints[numintersection].set_t(t[numintersection]);
            ++numintersection;
            // TODO compute cap plane intersection

            // check with cap plane
            Plane cap(m_vertex + m_axis * m_height, m_axis);
            IntervalSet capset;
            if (cap.clip(ray_, capset)) {
                if (capset.bounds()[0].t < t[numintersection-1]) {
                    t[numintersection] = t[numintersection-1];
                    ipoints[numintersection] = ipoints[numintersection-1];
                    --numintersection;
                }
                ipoints[numintersection] = *(capset.bounds()[0].data);
                delete capset.bounds()[0].data;
                delete capset.bounds()[1].data;
                return 2;
            } else {
                // must never reach this point !
                assert(false);
                return 0;
            }
        }
    }