void RayTracer::tracePhotons(Photon p, int bouncesLeft){
    //Only trace the photon if more than one bounce
    if (bouncesLeft > 0){
        //Get the intersected surface
        shared_ptr<UniversalSurfel> surfel = dynamic_pointer_cast<UniversalSurfel>(castRay(G3D::Ray(p.origin,p.direction).bumpedRay(0.0001), finf(), 0));
        if (surfel){
            p.origin = surfel->position;
            //Don't store for mirror surfaces
            if (!(surfel->glossyReflectionCoefficient.nonZero() && (surfel->glossyReflectionExponent == inf()))){
                Vector3 D = p.origin -  m_camera->frame().translation;
                //if (D.length() < 10){
                    if(castRay(G3D::Ray(m_camera->frame().translation,D).bumpedRay(0.0001), D.length(), 1)) {
                        photons.insert(p);
                    }
                //}
            }
            shared_ptr<Random> rnd = m_rnd[0];
            
            Vector3 wo;
            Color3 weight;
            //scatter the photon using the method provided by G3D. Used to be a lot of lines which got deleted
            surfel->scatter(PathDirection::SOURCE_TO_EYE, -p.direction, true, *rnd, weight, wo);
            //If it scatters, continue tracing
            if (wo.magnitude() > 0){
                p.direction = wo;
                p.power *= weight;
                tracePhotons(p, bouncesLeft - 1);
            }

            rnd.reset();
        }
    }
}
Example #2
0
bool SceneObject::castRayRendered(const Point3F &start, const Point3F &end, RayInfo *info)
{
   // By default, all ray checking against the rendered mesh will be passed
   // on to the collision mesh.  This saves having to define both methods
   // for simple objects.
   return castRay( start, end, info );
}
Example #3
0
std::tuple<cv::Mat, cv::Mat> SimpleRayCaster::renderZMasks() {
    cv::Mat fgMask(_res_y, _res_x, CV_32F);
    cv::Mat bgMask(_res_y, _res_x, CV_32F);

    for (int y=0; y<_res_y; y++) {
        for (int x=0; x<_res_x; x++) {

            Eigen::Vector2f co((float)x/(float)_res_x,(float)y/(float)_res_y);
            auto zvalues = castRay(co);
            float fgPixel = 0.0f;
            float bgPixel = 0.0f;

            /* only valid masks if there were 2 intersections */
            if (zvalues.size() == 2) {
                if (zvalues[0] < zvalues[1]) {
                    fgPixel = zvalues[0];
                    bgPixel = zvalues[1];
                } else {
                    fgPixel = zvalues[1];
                    bgPixel = zvalues[0];
                }
            }

            fgMask.at<float>(y,x) = fgPixel;
            bgMask.at<float>(y,x) = bgPixel;
        }
    } 

    return std::make_tuple(fgMask, bgMask);
}
Example #4
0
SceneNode *SceneManager::castRay( SceneNode *node, const Vec3f &rayOrig, const Vec3f &rayDir, float &minDist )
{
	if( !node->_active ) return 0x0;
	
	static Vec3f intsPos;
	SceneNode *nearestNode = 0x0;

	if( rayAABBIntersection( rayOrig, rayDir, node->_bBox.getMinCoords(), node->_bBox.getMaxCoords() ) )
	{
		if( node->checkIntersection( rayOrig, rayDir, intsPos ) )
		{
			float dist = (intsPos - rayOrig).length();
			if( dist < minDist )
			{
				nearestNode = node;
				minDist = dist;
			}
		}

		for( uint32 i = 0; i < node->_children.size(); ++i )
		{
			SceneNode *sn = castRay( node->_children[i], rayOrig, rayDir, minDist );
			if( sn != 0x0 ) nearestNode = sn;
		}
	}

	return nearestNode;
}
Example #5
0
bool PhysShape::castRayLocal(const Point3F &startLocal, const Point3F &endLocal, RayInfo* info)
{
    if (m_physInfo.owner)
    {
        const VectorF& scale = m_physInfo.owner->getScale();
        const MatrixF& objToWorld = m_physInfo.owner->getTransform();
        Point3F start(startLocal);
        Point3F end (endLocal);

        start.convolve(scale);
        end.convolve(scale);
        objToWorld.mulP(start);
        objToWorld.mulP(end);

        bool res = castRay(start,end,info);
        if (res && info)
        {
            info->normal = startLocal - endLocal;
            info->normal.normalize();

        }
        return res;
    }
    return false;
}
Example #6
0
void SceneView::handleDrop(float x, float y)
{
	const char* path = (const char*)m_app.getDragData().data;
	auto hit = castRay(x, y);

	if (hit.m_is_hit)
	{
		if (Lumix::PathUtils::hasExtension(path, "msh"))
		{
			auto* command = LUMIX_NEW(m_editor->getAllocator(), InsertMeshCommand)(
				*m_editor, hit.m_origin + hit.m_t * hit.m_dir, Lumix::Path(path));

			m_editor->executeCommand(command);
		}
		else if (Lumix::PathUtils::hasExtension(path, "mat") && hit.m_mesh)
		{
			auto* desc = Lumix::PropertyRegister::getDescriptor(RENDERABLE_TYPE, Lumix::crc32("Material"));
			auto drag_data = m_app.getDragData();
			m_editor->selectEntities(&hit.m_entity, 1);
			auto* model = m_pipeline->getScene()->getRenderableModel(hit.m_component);
			int mesh_index = 0;
			for (int i = 0; i < model->getMeshCount(); ++i)
			{
				if (&model->getMesh(i) == hit.m_mesh)
				{
					mesh_index = i;
					break;
				}
			}
			
			m_editor->setProperty(RENDERABLE_TYPE, mesh_index, *desc, drag_data.data, drag_data.size);
		}
	}
}
Radiance3 RayTracer::L_i(const Point3 P, const Vector3& wi, int bouncesLeft, Random& rnd) const{
    //Get the surfel hit and call L_o to compute radiance at the surfel
    shared_ptr<Surfel> surfel = castRay(G3D::Ray(P,wi).bumpedRay(0.0001), finf(), 0);
    if (surfel){
        return L_o(surfel, -wi, bouncesLeft, rnd);
    } else{
        //No surfel, return black
        return Radiance3(0,0,0);
    }
}
Example #8
0
void RayTracer::traceOnePhoton(int ignoreX, int ignoreY, int threadID) {
    ThreadData& threadData(m_threadData[threadID]);

    Photon photon;
    emitPhoton(*threadData.rnd, photon);

    const float MIN_POWER_THRESHOLD = 0.001f / m_settings.photon.numEmitted;

    float probabilityHint = 1.0;

    for (int numBounces = 0;
            (numBounces < m_settings.photon.numBounces) &&
            (photon.power.sum() > MIN_POWER_THRESHOLD);
            ++numBounces) {
        // Find the first surface
        float distance = finf();
        const shared_ptr<Surfel>& surfel = castRay(photon.position, -photon.wi, distance, false);

        if (isNull(surfel)) {
            return;
        }

        // Store the photon (if this is not the first bounce and it is
        // not a purely specular surface)
        if ((numBounces > 0) && surfel->nonZeroFiniteScattering()) {
            photon.effectRadius = photonEffectRadius(probabilityHint);

            // Update photon position. Store it slightly before it hit the surface
            // to improve filtering later.
            photon.position = surfel->position + photon.wi * min(photon.effectRadius, distance) / 4;

            // Store a copy of this photon
            m_photonList[threadID].append(photon);
        }

        // Scatter
        Color3  weight;
        Vector3 wo;
        float   probabilityScale;
        surfel->scatter(PathDirection::SOURCE_TO_EYE, photon.wi, true, *threadData.rnd, weight, wo, probabilityScale);

        probabilityHint *= probabilityScale;

        // Update photon power and direction
        photon.power *= weight;
        photon.wi = -wo;

        photon.position = bump(surfel, wo);
    }
}
Example #9
0
void SimpleRayCaster::renderDebugImage(int width, int height) {

    for (int y=0; y<height; y++) {
        for (int x=0; x<width; x++) {
            Eigen::Vector2f co((float)x/(float)width,(float)y/(float)height);
            auto zvalues = castRay(co);
            if (zvalues.size() > 0) {
                std::cout << "0";
            } else {
                std::cout << " ";
            }
        }
        std::cout << std::endl;
    }

    }
Example #10
0
bool RayTracer::visible(const Point3& Y, const Point3& X, bool shadowRay) const {
    Vector3 w(X - Y);
    float distance = w.length();
    w /= distance;

    distance -= BUMP_EPSILON * 2;

    shared_ptr<Surfel> surfel = castRay(Y + w * BUMP_EPSILON, w, distance, true);

    if (isNull(surfel)) {
        return true;
    } else if (shadowRay && notNull(surfel->surface) && ! surfel->surface->expressiveLightScatteringProperties.castsShadows) {
        // Re-cast the ray
        return visible(surfel->position, X, true);
    } else {
        // Hit a surface
        return false;
    }
}
Example #11
0
Radiance3 RayTracer::L_in(const Point3& X, const Vector3& wi, ThreadData& threadData, int bouncesLeft) const {
    if (bouncesLeft == 0) {
        // We aren't allowed to trace farther, so estimate from the
        // environment map
        return BACKGROUND_RADIANCE;
    }

    // Surface hit by the primary ray (at X)
    float maxDistance = finf();
    shared_ptr<Surfel> surfel(castRay(X, wi, maxDistance));

    if (notNull(surfel)) {
        // Hit something
        return L_out(surfel, -wi, threadData, bouncesLeft);
    } else {
        // Hit background
        return BACKGROUND_RADIANCE;
    }
}
Example #12
0
	GameObject * GameController::FindObjectAtScreenPosition(const Point &point)
	{
		if (mInstance) {
			glm::vec3 nearPoint = mCamera->Unproject(point, 0);
			glm::vec3 farPoint = mCamera->Unproject(point, 1);

			glm::vec3 direction = glm::normalize(farPoint - nearPoint);

			Ray castRay(nearPoint, direction);

			//mDebugRay->ClearPoints();
			//mDebugRay->AddPoint(nearPoint);
			//mDebugRay->AddPoint(castRay.ValueAt(1000));

			return mInstance->FindNearestObject(castRay);


		}

		return NULL;
	}
/* returns true if a point is in shadow from a light */
Color3 RayTracer::visiblePercentage(Ray ray, const shared_ptr<Light>& light, float distance) const{
    //Only computes if we are actually casting shadows
    if (m_settings.enableShadows && light->castsShadows()){
        //Increment the amount of shadow rays
        ++m_stats->shadowRays;
        //If partial coverage is enabled, we need to compute the actual percentage, otherwise just need to test visible
        if (m_settings.enablePartialCoverage){
            Color3 visibility(1,1,1);
            //the current position of shadow ray
            Point3 oldPosition = ray.origin();
            //Iterate through the surfels in between and multiply visibility by their trasmissiveness
            //Until we reach the original surface (distance <=0) or the visibility becomes 0
            while ((distance > 0) && !(visibility.clamp(0,1).isZero())){
                shared_ptr<UniversalSurfel> surfel = dynamic_pointer_cast<UniversalSurfel>(castRay(ray.bumpedRay(0.0001), distance, 0));
                //If no more surfel left, simply return
                if (!surfel){
                    return visibility;
                } else{
                    visibility *= surfel->transmissionCoefficient;
                }

                distance = distance - (surfel->position - oldPosition).magnitude();
                oldPosition = surfel->position;
                ray = Ray(oldPosition, ray.direction());
            }

            return visibility;
        } else{
            //If not doing partial coverage, just need to test visibility. Set anysurfel to 1 for faster intersection
            if(castRay(ray.bumpedRay(0.0001), distance, 1)) {
                return Color3(0,0,0);
            } else{
                return Color3(1,1,1);
            }
        }
    } else{
        //Non shadow casting always gives total visibility
        return Color3(1,1,1);
    }
}
Example #14
0
 void generateRays (
     std::vector<xe::sg::Ray> &rays,
     const xe::Vector2i &size, 
     const xe::Vector3f &cam_pos, 
     const xe::Vector3f &cam_up, 
     const xe::Vector3f &cam_dir, 
     const xe::Vector3f &cam_right) {
     
     assert(size.x > 0);
     assert(size.y > 0);
     assert(rays.size() == size.x*size.y);
 
     const xe::Vector2f sizef = (xe::Vector2f)size;
     const int rayCount = size.x * size.y;
     
     for (int i=0; i<rayCount; i++) {
         xe::Vector2i coord = computePixel(i, size);
         xe::Vector2f coordf = static_cast<xe::Vector2f>(coord);
         xe::sg::Ray ray = castRay(coordf, sizef, cam_pos, cam_up, cam_dir, cam_right);
         
         rays[i] = ray;
     }
 }
Example #15
0
btScalar RaycastCar::rayCast(WheelInfo& wheel)
{
    btScalar depth = -1;
    btScalar raylen = wheel.getSuspensionRestLength() + wheel.m_wheelsRadius;
    btVector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen);
    const btVector3& source = wheel.m_raycastInfo.m_hardPointWS;
    wheel.m_raycastInfo.m_contactPointWS = source + rayvector;
    const btVector3& target = wheel.m_raycastInfo.m_contactPointWS;
    btScalar param = btScalar(0.0);
    RaycasterResult rayResults;
    void * object = castRay(source,target,rayResults);
    wheel.m_raycastInfo.m_groundObject = 0;
    if (object)
    {
        param = rayResults.m_distFraction;
        depth = raylen * rayResults.m_distFraction;
        wheel.m_raycastInfo.m_contactNormalWS  = rayResults.m_hitNormalInWorld;
        wheel.m_raycastInfo.m_isInContact = true;
#ifdef USE_TMP_FIXED_OBJECT
        wheel.m_raycastInfo.m_groundObject = tmp_fixed;
#else
        wheel.m_raycastInfo.m_groundObject = object;
#endif
        btScalar hitDistance = param*raylen;
        wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelsRadius;
        //clamp on max suspension travel
        btScalar minSuspensionLength = wheel.getSuspensionRestLength()-wheel.m_maxSuspensionTravelCm*btScalar(0.01f);
        btScalar maxSuspensionLength = wheel.getSuspensionRestLength()+wheel.m_maxSuspensionTravelCm*btScalar(0.01f);
        if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength)
        {
            wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength;
        }
        if (wheel.m_raycastInfo.m_suspensionLength > maxSuspensionLength)
        {
            wheel.m_raycastInfo.m_suspensionLength = maxSuspensionLength;
        }
        wheel.m_raycastInfo.m_contactPointWS = rayResults.m_hitPointInWorld;
        btScalar denominator= wheel.m_raycastInfo.m_contactNormalWS.dot( wheel.m_raycastInfo.m_wheelDirectionWS );
        btVector3 chassis_velocity_at_contactPoint;
        btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS-getRigidBody()->getCenterOfMassPosition();
        chassis_velocity_at_contactPoint = getRigidBody()->getVelocityInLocalPoint(relpos);
        btScalar projVel = wheel.m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint );
        if ( denominator >= btScalar(-0.1f))
        {
            wheel.m_suspensionRelativeVelocity = btScalar(0.0f);
            wheel.m_clippedInvContactDotSuspension = btScalar(1.0f) / btScalar(0.1f);
        }
        else
        {
            btScalar inv = btScalar(-1.0f) / denominator;
            wheel.m_suspensionRelativeVelocity = projVel * inv;
            wheel.m_clippedInvContactDotSuspension = inv;
        }
    }
    else
    {
        //put wheel info as in rest position
        wheel.m_raycastInfo.m_suspensionLength = wheel.getSuspensionRestLength();
        wheel.m_suspensionRelativeVelocity = btScalar(0.0f);
        wheel.m_raycastInfo.m_contactNormalWS = - wheel.m_raycastInfo.m_wheelDirectionWS;
        wheel.m_clippedInvContactDotSuspension = btScalar(1.0f);
    }
    return depth;
}