Example #1
0
// ImageFilm Method Definitions
ImageFilm::ImageFilm(int xres, int yres,
                     Filter *filt, const float crop[4],
		             const string &fn, bool premult, int wf)
	: Film(xres, yres) {
	filter = filt;
	memcpy(cropWindow, crop, 4 * sizeof(float));
	filename = fn;
	premultiplyAlpha = premult;
	writeFrequency = sampleCount = wf;
	// Compute film image extent
	xPixelStart = Ceil2Int(xResolution * cropWindow[0]);
	xPixelCount =
		max(1, Ceil2Int(xResolution * cropWindow[1]) - xPixelStart);
	yPixelStart =
		Ceil2Int(yResolution * cropWindow[2]);
	yPixelCount =
		max(1, Ceil2Int(yResolution * cropWindow[3]) - yPixelStart);
	// Allocate film image storage
	pixels = new BlockedArray<Pixel>(xPixelCount, yPixelCount);
	// Precompute filter weight table
	#define FILTER_TABLE_SIZE 16
	filterTable =
		new float[FILTER_TABLE_SIZE * FILTER_TABLE_SIZE];
	float *ftp = filterTable;
	for (int y = 0; y < FILTER_TABLE_SIZE; ++y) {
		float fy = ((float)y + .5f) * filter->yWidth /
			FILTER_TABLE_SIZE;
		for (int x = 0; x < FILTER_TABLE_SIZE; ++x) {
			float fx = ((float)x + .5f) * filter->xWidth /
				FILTER_TABLE_SIZE;
			*ftp++ = filter->Evaluate(fx, fy);
		}
	}
}
Example #2
0
PotentialField::PotentialField(const BBox& bbox, double div_size)
	: bound(bbox), division(div_size)
{
	Vector3D diag = bound.getDiagnal();
	grids[0] = Ceil2Int(diag.x / division);
	grids[1] = Ceil2Int(diag.y / division);
	grids[2] = Ceil2Int(diag.z / division);
}
Example #3
0
void ImageFilm::AddSample(const Sample &sample, const Ray &ray, const Spectrum &L, float alpha) {
	// Compute sample's raster extent
	float dImageX = sample.imageX - 0.5f;
	float dImageY = sample.imageY - 0.5f;
	int x0 = Ceil2Int (dImageX - filter->xWidth);
	int x1 = Floor2Int(dImageX + filter->xWidth);
	int y0 = Ceil2Int (dImageY - filter->yWidth);
	int y1 = Floor2Int(dImageY + filter->yWidth);
	x0 = max(x0, xPixelStart);
	x1 = min(x1, xPixelStart + xPixelCount - 1);
	y0 = max(y0, yPixelStart);
	y1 = min(y1, yPixelStart + yPixelCount - 1);
	if ((x1-x0) < 0 || (y1-y0) < 0) return;
	// Loop over filter support and add sample to pixel arrays
	// Precompute $x$ and $y$ filter table offsets
	int *ifx = (int *)alloca((x1-x0+1) * sizeof(int));
	for (int x = x0; x <= x1; ++x) {
		float fx = fabsf((x - dImageX) *
		                 filter->invXWidth * FILTER_TABLE_SIZE);
		ifx[x-x0] = min(Floor2Int(fx), FILTER_TABLE_SIZE-1);
	}
	int *ify = (int *)alloca((y1-y0+1) * sizeof(int));
	for (int y = y0; y <= y1; ++y) {
		float fy = fabsf((y - dImageY) *
		                 filter->invYWidth * FILTER_TABLE_SIZE);
		ify[y-y0] = min(Floor2Int(fy), FILTER_TABLE_SIZE-1);
	}
	for (int y = y0; y <= y1; ++y)
		for (int x = x0; x <= x1; ++x) {
			// Evaluate filter value at $(x,y)$ pixel
			int offset = ify[y-y0]*FILTER_TABLE_SIZE + ifx[x-x0];
			float filterWt = filterTable[offset];
			//printf("BEFORE add weight : ");
			//L.printSelf();
			// Update pixel values with filtered sample contribution
			Pixel &pixel = (*pixels)(x - xPixelStart, y - yPixelStart);
			
			pixel.L.AddWeighted(filterWt, L);
			//printf("AFTER add weight : ");
			//pixel.L.printSelf();
			pixel.alpha += alpha * filterWt;
			pixel.weightSum += filterWt;
		}
	// Possibly write out in-progress image
	if (--sampleCount == 0) {
		WriteImage();
		sampleCount = writeFrequency;
	}
}
Example #4
0
Vector3D PotentialField::gradiance(const Point3D& m_pos) const
{
	Vector3D ret;
	Vector3D diag = m_pos - bound.pMin;
	if (diag.x < 0 || diag.y < 0 || diag.z < 0)
	{
		return ret;
	}
	// ceil grid index
	double divIdx[3] = { diag.x / division, diag.y / division, diag.z / division };
	int ceilIdx = Ceil2Int(divIdx[0]) + Ceil2Int(divIdx[1]) * grids[1]
		+ Ceil2Int(divIdx[2]) * grids[0] * grids[1];
	int floorIdx = Floor2Int(divIdx[0]) + Floor2Int(divIdx[1]) * grids[1]
		+ Floor2Int(divIdx[2]) * grids[0] * grids[1];
	ret = lerp(m_field[floorIdx], m_field[ceilIdx], diag.getLength() / divDiag);

	return ret;
}
Example #5
0
Spectrum EmissionIntegrator::Li(const Scene *scene,
                                const Renderer *renderer, const RayDifferential &ray,
                                const Sample *sample, RNG &rng, Spectrum *T,
                                MemoryArena &arena) const {
    VolumeRegion *vr = scene->volumeRegion;
    Assert(sample != NULL);
    float t0, t1;
    if (!vr || !vr->IntersectP(ray, &t0, &t1) || (t1-t0) == 0.f) {
        *T = Spectrum(1.f);
        return 0.f;
    }
    // Do emission-only volume integration in _vr_
    Spectrum Lv(0.);

    // Prepare for volume integration stepping
    int nSamples = Ceil2Int((t1-t0) / stepSize);
    float step = (t1 - t0) / nSamples;
    Spectrum Tr(1.f);
    pbrt::Point p = ray(t0), pPrev;
    Vector w = -ray.d;
    t0 += sample->oneD[scatterSampleOffset][0] * step;
    for (int i = 0; i < nSamples; ++i, t0 += step) {
        // Advance to sample at _t0_ and update _T_
        pPrev = p;
        p = ray(t0);
        Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, ray.time, ray.depth);
        Spectrum stepTau = vr->tau(tauRay,
                                   .5f * stepSize, rng.RandomFloat());
        Tr *= Exp(-stepTau);

        // Possibly terminate ray marching if transmittance is small
        if (Tr.y() < 1e-3) {
            const float continueProb = .5f;
            if (rng.RandomFloat() > continueProb) {
                Tr = 0.f;
                break;
            }
            Tr /= continueProb;
        }

        // Compute emission-only source term at _p_
        Lv += Tr * vr->Lve(p, w, ray.time);
    }
    *T = Tr;
    return Lv * step;
}
Example #6
0
Spectrum VSDScatteringIntegrator::LiSingle(const Scene *scene, const Renderer *renderer,
        const RayDifferential &ray, const Sample *sample, RNG &rng,
        Spectrum *T, MemoryArena &arena) const {
    VolumeRegion *vr = scene->volumeRegion;
    float t0, t1;
    vr->IntersectP(ray, &t0, &t1);

    // Do single scattering volume integration in _vr_
    Spectrum Lv(0.);

    // Prepare for volume integration stepping
    int nSamples = Ceil2Int((t1-t0) / stepSize);
    float step = (t1 - t0) / nSamples;
    Spectrum Tr(1.f);
    Point p = ray(t0), pPrev;
    t0 += sample->oneD[scatterSampleOffset][0] * step;

    // Compute the emission from the voxels, not from the light sources
    for (int i = 0; i < nSamples; ++i, t0 += step) {
        // Advance to sample at _t0_ and update _T_
        pPrev = p;
        p = ray(t0);
        Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, ray.time, ray.depth);
        Spectrum stepTau = vr->tau(tauRay,
                                   .5f * stepSize, rng.RandomFloat());
        Tr *= Exp(-stepTau);

        // Possibly terminate ray marching if transmittance is small
        if (Tr.y() < 1e-3) {
            const float continueProb = .5f;
            if (rng.RandomFloat() > continueProb) {
                Tr = 0.f;
                break;
            }
            Tr /= continueProb;
        }

        // Compute emission term at _p_
        Lv += Tr * vr->PhotonDensity(p);
    }
    *T = Tr;
    return Lv * step;
}
Example #7
0
Spectrum SingleScatteringFluorescenceRWLIntegrator::Li(const Scene *scene,
        const Renderer *renderer, const RayDifferential &ray,
        const Sample *sample, RNG &rng, Spectrum *T, MemoryArena &arena) const {
    VolumeRegion *vr = scene->volumeRegion;
    float t0, t1;
    if (!vr || !vr->IntersectP(ray, &t0, &t1) || (t1-t0) == 0.f) {
        *T = 1.f;
        return 0.f;
    }
    // Do single scattering volume integration in _vr_
    Spectrum Lv(0.);

    // Prepare for volume integration stepping
    int nSamples = Ceil2Int((t1-t0) / stepSize);
    float step = (t1 - t0) / nSamples;
    Spectrum Tr(1.f);
    Point p = ray(t0), pPrev;
    Vector w = -ray.d;
    t0 += sample->oneD[scatterSampleOffset][0] * step;

    // Compute sample patterns for single scattering samples
    float *lightNum = arena.Alloc<float>(nSamples);
    LDShuffleScrambled1D(1, nSamples, lightNum, rng);
    float *lightComp = arena.Alloc<float>(nSamples);
    LDShuffleScrambled1D(1, nSamples, lightComp, rng);
    float *lightPos = arena.Alloc<float>(2*nSamples);
    LDShuffleScrambled2D(1, nSamples, lightPos, rng);
    uint32_t sampOffset = 0;
    for (int i = 0; i < nSamples; ++i, t0 += step) {
        // Advance to sample at _t0_ and update _T_
        pPrev = p;
        p = ray(t0);

        Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, ray.time, ray.depth);
        Spectrum stepTau = vr->tau(tauRay, 0.5f * stepSize, rng.RandomFloat());
        Tr *= Exp(-stepTau);

        // Possibly terminate ray marching if transmittance is small
        if (Tr.y() < 1e-3) {
            const float continueProb = .5f;
            if (rng.RandomFloat() > continueProb) {
                Tr = 0.f;
                break;
            }
            Tr /= continueProb;
        }

        // Compute fluorescence emission
        Spectrum sigma = vr->Mu(p, w, ray.time);
        if (!sigma.IsBlack() && scene->lights.size() > 0) {
            int nLights = scene->lights.size();
            int ln = min(Floor2Int(lightNum[sampOffset] * nLights),
                         nLights-1);
            Light *light = scene->lights[ln];

            // Add contribution of _light_ due to the in-scattering at _p_
            float pdf;
            VisibilityTester vis;
            Vector wo;
            LightSample ls(lightComp[sampOffset], lightPos[2*sampOffset],
                           lightPos[2*sampOffset+1]);
            Spectrum L = light->Sample_L(p, 0.f, ls, ray.time, &wo, &pdf, &vis);
            if (!L.IsBlack() && pdf > 0.f && vis.Unoccluded(scene)) {
                Spectrum Ld = L * vis.Transmittance(scene, renderer, NULL, rng,
                                                    arena);
                int lambdaExcIndex = light->GetLaserWavelengthIndex();
                float Lpower = Ld.GetLaserEmissionPower(lambdaExcIndex);
                float yield = vr->Yeild(Point());
                Spectrum fEx = vr->fEx(Point());
                Spectrum fEm = vr->fEm(Point());
                float scale = fEx.GetSampleValueAtWavelengthIndex(lambdaExcIndex);
                Lv += Lpower * Tr * sigma * vr->p(p, w, -wo, ray.time) *
                        scale * fEm * yield * float(nLights) / pdf;
            }
        }
        ++sampOffset;
    }
    *T = Tr;
    return Lv * step;
}
Example #8
0
Spectrum SingleScatteringIntegrator::Li(const Scene *scene, const Renderer *renderer,
        const RayDifferential &ray, const Sample *sample,
        Spectrum *T, MemoryArena &arena) const {
    VolumeRegion *vr = scene->volumeRegion;
    float t0, t1;
    if (!vr || !vr->IntersectP(ray, &t0, &t1)) {
        *T = 1.f;
        return 0.f;
    }
    // Do single scattering volume integration in _vr_
    Spectrum Lv(0.);

    // Prepare for volume integration stepping
    int nSamples = Ceil2Int((t1-t0) / stepSize);
    float step = (t1 - t0) / nSamples;
    Spectrum Tr(1.f);
    Point p = ray(t0), pPrev;
    Vector w = -ray.d;
    t0 += sample->oneD[scatterSampleOffset][0] * step;

    // Compute sample patterns for single scattering samples
    float *lightNum = arena.Alloc<float>(nSamples);
    LDShuffleScrambled1D(1, nSamples, lightNum, *sample->rng);
    float *lightComp = arena.Alloc<float>(nSamples);
    LDShuffleScrambled1D(1, nSamples, lightComp, *sample->rng);
    float *lightPos = arena.Alloc<float>(2*nSamples);
    LDShuffleScrambled2D(1, nSamples, lightPos, *sample->rng);
    u_int sampOffset = 0;
    for (int i = 0; i < nSamples; ++i, t0 += step) {
        // Advance to sample at _t0_ and update _T_
        pPrev = p;
        p = ray(t0);
        Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, ray.time, ray.depth);
        Spectrum stepTau = vr->tau(tauRay,
                                   .5f * stepSize, sample->rng->RandomFloat());
        Tr *= Exp(-stepTau);

        // Possibly terminate ray marching if transmittance is small
        if (Tr.y() < 1e-3) {
            const float continueProb = .5f;
            if (sample->rng->RandomFloat() > continueProb) break;
            Tr /= continueProb;
        }

        // Compute single-scattering source term at _p_
        Lv += Tr * vr->Lve(p, w, ray.time);
        Spectrum ss = vr->sigma_s(p, w, ray.time);
        if (!ss.IsBlack() && scene->lights.size() > 0) {
            int nLights = scene->lights.size();
            int ln = min(Floor2Int(lightNum[sampOffset] * nLights),
                         nLights-1);
            Light *light = scene->lights[ln];
            // Add contribution of _light_ due to scattering at _p_
            float pdf;
            VisibilityTester vis;
            Vector wo;
            LightSample ls(lightComp[sampOffset], lightPos[2*sampOffset],
                           lightPos[2*sampOffset+1]);
            Spectrum L = light->Sample_L(p, 0.f, ls, ray.time, &wo, &pdf, &vis);
            if (!L.IsBlack() && pdf > 0.f && vis.Unoccluded(scene)) {
                Spectrum Ld = L * vis.Transmittance(scene, renderer, NULL, sample->rng, arena);
                Lv += Tr * ss * vr->p(p, w, -wo, ray.time) * Ld * float(nLights) / pdf;
            }
        }
        ++sampOffset;
    }
    *T = Tr;
    return Lv * step;
}
Example #9
0
Spectrum PhotonVolumeIntegrator::Li(const Scene *scene, const Renderer *renderer,
        const RayDifferential &ray, const Sample *sample, RNG &rng,
        Spectrum *T, MemoryArena &arena) const {
 	
 	VolumeRegion *vr = scene->volumeRegion;
    RainbowVolume* rv = dynamic_cast<RainbowVolume*>(vr);
 	KdTree<Photon>* volumeMap = photonShooter->volumeMap; 

 	float t0, t1;
 	if (!vr || !vr->IntersectP(ray, &t0, &t1) || (t1-t0) == 0.f){
 		*T = 1.f;
 	 	return 0.f;
 	 }
 	// Do single scattering & photon multiple scattering volume integration in _vr_
 	Spectrum Lv(0.);


 	// Prepare for volume integration stepping
 	int nSamples = Ceil2Int((t1-t0) / stepSize);
 	float step = (t1 - t0) / nSamples;
 	Spectrum Tr(1.f);
 	Point p = ray(t0), pPrev;
 	Vector w = -ray.d;
 	t0 += sample->oneD[scatterSampleOffset][0] * step;

 	float *lightNum = arena.Alloc<float>(nSamples);
    LDShuffleScrambled1D(1, nSamples, lightNum, rng);
    float *lightComp = arena.Alloc<float>(nSamples);
    LDShuffleScrambled1D(1, nSamples, lightComp, rng);
    float *lightPos = arena.Alloc<float>(2*nSamples);
    LDShuffleScrambled2D(1, nSamples, lightPos, rng);
 	int sampOffset = 0;

 	ClosePhoton *lookupBuf = new ClosePhoton[nSamples];

 	for (int i = 0; i < nSamples; ++i, t0 += step) {
 		// Advance to sample at _t0_ and update _T_
 		pPrev = p;
 		p = ray(t0);

 		Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, ray.time, ray.depth);

 		Spectrum stepTau = vr->tau(tauRay,.5f * stepSize, rng.RandomFloat());
 		Tr = Exp(-stepTau);

 		// Possibly terminate raymarching if transmittance is small.
 		if (Tr.y() < 1e-3) {
 			const float continueProb = .5f;
 			if (rng.RandomFloat() > continueProb){
 				Tr = 0.f;
 				break;
 			}
 			Tr /= continueProb;
 		}
		
		
 		// Compute single-scattering source term at _p_ & photon mapped MS
 		Spectrum L_i(0.);
 		Spectrum L_d(0.);
 		Spectrum L_ii(0.);
 		
 		// Lv += Tr*vr->Lve(p, w, ray.time);
 		Spectrum ss = vr->sigma_s(p, w, ray.time);
 		Spectrum sa = vr->sigma_a(p, w, ray.time);

 		if (!ss.IsBlack() && scene->lights.size() > 0) {
 			int nLights = scene->lights.size();
 			int ln =
 				min(Floor2Int(lightNum[sampOffset] * nLights),
 				    nLights-1);
 			Light *light = scene->lights[ln];
 			// Add contribution of _light_ due to scattering at _p_
 			float pdf;
 			VisibilityTester vis;
 			Vector wo;

 			LightSample ls(lightComp[sampOffset], lightPos[2*sampOffset],
                           lightPos[2*sampOffset+1]);
            Spectrum L = light->Sample_L(p, 0.f, ls, ray.time, &wo, &pdf, &vis);
            

 			if (!L.IsBlack() && pdf > 0.f && vis.Unoccluded(scene)) {

                Spectrum Ld = L * vis.Transmittance(scene,renderer, NULL, rng, arena);
                if(rv){
                    L_d = rv->rainbowReflection(Ld, ray.d, wo);
                }
                else {
                    L_d = vr->p(p, w, -wo, ray.time) * Ld * float(nLights)/pdf;
                }
 			}
 		}
		// Compute 'indirect' in-scattered radiance from photon map
        if(!rv){
            L_ii += LPhoton(volumeMap, nUsed, lookupBuf, w, p, vr, maxDistSquared, ray.time);
        }
        
		// Compute total in-scattered radiance
		if (sa.y()!=0.0 || ss.y()!=0.0)
			L_i = L_d + (ss/(sa+ss))*L_ii;
		else
			L_i = L_d;

		Spectrum nLv = (sa*vr->Lve(p,w,ray.time)*step) + (ss*L_i*step) + (Tr * Lv)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ;

		Lv = nLv;
 		sampOffset++;
 	}
 	*T = Tr;
	return Lv;
}
void CreateRadianceProbes::Render(const Scene *scene) {
    // Compute scene bounds and initialize probe integrators
    if (bbox.pMin.x > bbox.pMax.x)
        bbox = scene->WorldBound();
    surfaceIntegrator->Preprocess(scene, camera, this);
    volumeIntegrator->Preprocess(scene, camera, this);
    Sample *origSample = new Sample(NULL, surfaceIntegrator, volumeIntegrator,
                                    scene);

    // Compute sampling rate in each dimension
    Vector delta = bbox.pMax - bbox.pMin;
    int nProbes[3];
    for (int i = 0; i < 3; ++i)
        nProbes[i] = max(1, Ceil2Int(delta[i] / probeSpacing));

    // Allocate SH coefficient vector pointers for sample points
    int count = nProbes[0] * nProbes[1] * nProbes[2];
    Spectrum **c_in = new Spectrum *[count];
    for (int i = 0; i < count; ++i)
        c_in[i] = new Spectrum[SHTerms(lmax)];

    // Compute random points on surfaces of scene

    // Create scene bounding sphere to catch rays that leave the scene
    Point sceneCenter;
    float sceneRadius;
    scene->WorldBound().BoundingSphere(&sceneCenter, &sceneRadius);
    Transform ObjectToWorld(Translate(sceneCenter - Point(0,0,0)));
    Transform WorldToObject(Inverse(ObjectToWorld));
    Reference<Shape> sph = new Sphere(&ObjectToWorld, &WorldToObject,
        true, sceneRadius, -sceneRadius, sceneRadius, 360.f);
    Reference<Material> nullMaterial = Reference<Material>(NULL);
    GeometricPrimitive sphere(sph, nullMaterial, NULL);
    vector<Point> surfacePoints;
    uint32_t nPoints = 32768, maxDepth = 32;
    surfacePoints.reserve(nPoints + maxDepth);
    Point pCamera = camera->CameraToWorld(camera->shutterOpen,
                                          Point(0, 0, 0));
    surfacePoints.push_back(pCamera);
    RNG rng;
    while (surfacePoints.size() < nPoints) {
        // Generate random path from camera and deposit surface points
        Point pray = pCamera;
        Vector dir = UniformSampleSphere(rng.RandomFloat(), rng.RandomFloat());
        float rayEpsilon = 0.f;
        for (uint32_t i = 0; i < maxDepth; ++i) {
            Ray ray(pray, dir, rayEpsilon, INFINITY, time);

            Intersection isect;
            if (!scene->Intersect(ray, &isect) &&
                !sphere.Intersect(ray, &isect))
                break;

            surfacePoints.push_back(ray(ray.maxt));

            DifferentialGeometry &hitGeometry = isect.dg;
            pray = isect.dg.p;
            rayEpsilon = isect.rayEpsilon;
            hitGeometry.nn = Faceforward(hitGeometry.nn, -ray.d);

            dir = UniformSampleSphere(rng.RandomFloat(), rng.RandomFloat());
            dir = Faceforward(dir, hitGeometry.nn);
        }
    }

    // Launch tasks to compute radiance probes at sample points
    vector<Task *> tasks;
    ProgressReporter prog(count, "Radiance Probes");
    for (int i = 0; i < count; ++i)
        tasks.push_back(new CreateRadProbeTask(i, nProbes, time,
                                   bbox, lmax, includeDirectInProbes,
                                   includeIndirectInProbes, nIndirSamples,
                                   prog, origSample, surfacePoints,
                                   scene, this, c_in[i]));
    EnqueueTasks(tasks);
    WaitForAllTasks();
    for (uint32_t i = 0; i < tasks.size(); ++i)
        delete tasks[i];
    prog.Done();

    // Write radiance probe coefficients to file
    FILE *f = fopen(filename.c_str(), "w");
    if (f) {
        if (fprintf(f, "%d %d %d\n", lmax, includeDirectInProbes?1:0, includeIndirectInProbes?1:0) < 0 ||
            fprintf(f, "%d %d %d\n", nProbes[0], nProbes[1], nProbes[2]) < 0 ||
            fprintf(f, "%f %f %f %f %f %f\n", bbox.pMin.x, bbox.pMin.y, bbox.pMin.z,
                    bbox.pMax.x, bbox.pMax.y, bbox.pMax.z) < 0) {
            Error("Error writing radiance file \"%s\" (%s)", filename.c_str(),
                  strerror(errno));
            exit(1);
        }

        for (int i = 0; i < nProbes[0] * nProbes[1] * nProbes[2]; ++i) {
            for (int j = 0; j < SHTerms(lmax); ++j) {
                fprintf(f, "  ");
                if (c_in[i][j].Write(f) == false) {
                    Error("Error writing radiance file \"%s\" (%s)", filename.c_str(),
                          strerror(errno));
                    exit(1);
                }
                fprintf(f, "\n");
            }
            fprintf(f, "\n");
        }
        fclose(f);
    }
    for (int i = 0; i < nProbes[0] * nProbes[1] * nProbes[2]; ++i)
        delete[] c_in[i];
    delete[] c_in;
    delete origSample;
}
Example #11
0
//-----------------------------------------------------------------------------
// Draws shield decals
//-----------------------------------------------------------------------------
void C_Shield::DrawShieldDecals( Vector* pt, bool hitDecals )
{
	if (m_Decals.Size() == 0)
		return;

	// Compute ripples:
	for ( int r = m_Decals.Size(); --r >= 0; )
	{
		// At the moment, nothing passes!
		bool passDecal = false;
		if ((!hitDecals) && (passDecal == hitDecals))
			continue;

		SetCurrentDecal( r );

		// We have to force a flush here because we're changing the proxy state
		if (!hitDecals)
			materials->Bind( m_pPassDecal, (IClientRenderable*)this );
		else
			materials->Bind( passDecal ? m_pPassDecal2 : m_pHitDecal, (IClientRenderable*)this );

		float dtime = gpGlobals->curtime - m_Decals[r].m_StartTime;
		float decay = exp( -( 2 * dtime) );

		// Retire the animation if it wraps
		// This gets set by TextureAnimatedWrapped above
		if ((m_Decals[r].m_StartTime < 0.0f) || (decay < 1e-3))
		{
			m_Decals.Remove(r);
			continue;
		}

		IMesh* pMesh = materials->GetDynamicMesh();

		// Figure out the quads we must mod2x....
		float u0 = m_Decals[r].m_RippleU - m_Decals[r].m_Radius;
		float u1 = m_Decals[r].m_RippleU + m_Decals[r].m_Radius;
		float v0 = m_Decals[r].m_RippleV - m_Decals[r].m_Radius;
		float v1 = m_Decals[r].m_RippleV + m_Decals[r].m_Radius;
		float du = u1 - u0;
		float dv = v1 - v0;

		int i0 = Floor2Int( v0 * (m_SubdivisionCount - 1) );
		int i1 = Ceil2Int( v1 * (m_SubdivisionCount - 1) );
		int j0 = Floor2Int( u0 * (m_SubdivisionCount - 1) );
		int j1 = Ceil2Int( u1 * (m_SubdivisionCount - 1) );
		if (i0 < 0)
			i0 = 0;
		if (i1 >= m_SubdivisionCount)
			i1 = m_SubdivisionCount - 1;
		if (j0 < 0)
			j0 = 0;
		if (j1 >= m_SubdivisionCount)
			j1 = m_SubdivisionCount - 1;

		int numTriangles = (i1 - i0) * (j1 - j0) * 2;

		CMeshBuilder meshBuilder;
		meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, numTriangles );

		float decalDu = m_InvSubdivisionCount / du;
		float decalDv = m_InvSubdivisionCount / dv;

		unsigned char color[3];
		color[0] = s_ImpactDecalColor[0] * decay;
		color[1] = s_ImpactDecalColor[1] * decay;
		color[2] = s_ImpactDecalColor[2] * decay;

		for ( int i = i0; i < i1; ++i)
		{
			float t = (float)i * m_InvSubdivisionCount;
			for (int j = j0; j < j1; ++j)
			{
				float s = (float)j * m_InvSubdivisionCount;
				int idx = i * m_SubdivisionCount + j;

				// Compute (u,v) into the decal
				float decalU = (s - u0) / du;
				float decalV = (t - v0) / dv;

				meshBuilder.Position3fv( pt[idx].Base() );
				meshBuilder.Color3ubv( color );
				meshBuilder.TexCoord2f( 0, decalU, decalV );
				meshBuilder.AdvanceVertex();

				meshBuilder.Position3fv( pt[idx + m_SubdivisionCount].Base() );
				meshBuilder.Color3ubv( color );
				meshBuilder.TexCoord2f( 0, decalU, decalV + decalDv );
				meshBuilder.AdvanceVertex();

				meshBuilder.Position3fv( pt[idx + 1].Base() );
				meshBuilder.Color3ubv( color );
				meshBuilder.TexCoord2f( 0, decalU + decalDu, decalV );
				meshBuilder.AdvanceVertex();

				meshBuilder.Position3fv( pt[idx + 1].Base() );
				meshBuilder.Color3ubv( color );
				meshBuilder.TexCoord2f( 0, decalU + decalDu, decalV );
				meshBuilder.AdvanceVertex();

				meshBuilder.Position3fv( pt[idx + m_SubdivisionCount].Base() );
				meshBuilder.Color3ubv( color );
				meshBuilder.TexCoord2f( 0, decalU, decalV + decalDv );
				meshBuilder.AdvanceVertex();

				meshBuilder.Position3fv( pt[idx + m_SubdivisionCount + 1].Base() );
				meshBuilder.Color3ubv( color );
				meshBuilder.TexCoord2f( 0, decalU + decalDu, decalV + decalDv );
				meshBuilder.AdvanceVertex();
			}
		}

		meshBuilder.End();
		pMesh->Draw();
	}
}
Example #12
0
#endif

// ImageFilm Method Definitions
FalseColorFilm::FalseColorFilm(int xres, int yres, Filter *filt, const float crop[4],
                     const string &fn, bool openWindow)
#ifdef PBRT_FILM_FALSECOLOR_LOCK
: Film(xres, yres), mutex(*Mutex::Create()), changed(false)
#else
: Film(xres, yres), changed(false)
#endif
{
    filter = filt;
    memcpy(cropWindow, crop, 4 * sizeof(float));
    filename = fn;
    // Compute film image extent
    xPixelStart = Ceil2Int(xResolution * cropWindow[0]);
    xPixelCount = max(1, Ceil2Int(xResolution * cropWindow[1]) - xPixelStart);
    yPixelStart = Ceil2Int(yResolution * cropWindow[2]);
    yPixelCount = max(1, Ceil2Int(yResolution * cropWindow[3]) - yPixelStart);
    
    // Allocate film image storage
    pixels = new BlockedArray<Pixel>(xPixelCount, yPixelCount);
    
    // Possibly open window for image display
    if (openWindow || PbrtOptions.openWindow) {
        Warning("Support for opening image display window not available in this build.");
    }
}


void FalseColorFilm::AddSample(const CameraSample &sample,
//------------------------------------------------------------------------------
// Purpose : Window has been touched.  Break out pieces based on touching
//			 entity's bounding box
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CBreakableSurface::SurfaceTouch( CBaseEntity *pOther )
{
	// If tile only break if object is moving fast
	if (m_nSurfaceType == SHATTERSURFACE_TILE)
	{
		Vector vVel;
		pOther->GetVelocity( &vVel, NULL );
		if (vVel.Length() < 500)
		{
			return;
		}
	}

	// Find nearest point on plane for max
	Vector vecAbsMins, vecAbsMaxs;
	pOther->CollisionProp()->WorldSpaceAABB( &vecAbsMins, &vecAbsMaxs );
	Vector vToPlane		= (vecAbsMaxs - m_vCorner);
	float  vDistToPlane = DotProduct(m_vNormal,vToPlane);
	Vector vTouchPos	= vecAbsMaxs + vDistToPlane*m_vNormal;

	float flMinsWidth,flMinsHeight;
	PanePos(vTouchPos, &flMinsWidth, &flMinsHeight);

	// Find nearest point on plane for mins
	vToPlane		= (vecAbsMins - m_vCorner);
	vDistToPlane = DotProduct(m_vNormal,vToPlane);
	vTouchPos	= vecAbsMins + vDistToPlane*m_vNormal;

	float flMaxsWidth,flMaxsHeight;
	PanePos(vTouchPos, &flMaxsWidth, &flMaxsHeight);

	int nMinWidth = Floor2Int(MAX(0,		MIN(flMinsWidth,flMaxsWidth)));
	int nMaxWidth = Ceil2Int(MIN(m_nNumWide,MAX(flMinsWidth,flMaxsWidth)));

	int nMinHeight = Floor2Int(MAX(0,		MIN(flMinsHeight,flMaxsHeight)));
	int nMaxHeight = Ceil2Int(MIN(m_nNumHigh,MAX(flMinsHeight,flMaxsHeight)));

	Vector vHitVel;
	pOther->GetVelocity( &vHitVel, NULL );

	// Move faster then penetrating object so can see shards
	vHitVel *= 5;

	// If I'm not broken yet, break me
	if ( !m_bIsBroken )
	{
		Die( pOther, vHitVel );
	}

	for (int height=nMinHeight;height<nMaxHeight;height++)
	{
		// Randomly break the one before so it doesn't look square
		if (random->RandomInt(0,1))
		{
			ShatterPane(nMinWidth-1, height,vHitVel,pOther->GetLocalOrigin());
		}
		for (int width=nMinWidth;width<nMaxWidth;width++)
		{
			ShatterPane(width, height,vHitVel,pOther->GetLocalOrigin());
		}
		// Randomly break the one after so it doesn't look square
		if (random->RandomInt(0,1))
		{
			ShatterPane(nMaxWidth+1, height,vHitVel,pOther->GetLocalOrigin());
		}
	}
}