/*
This file is part of Mitsuba, a physically based rendering system.
Copyright (c) 2007-2010 by Wenzel Jakob and others.
Mitsuba is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License Version 3
as published by the Free Software Foundation.
Mitsuba is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include "preview_proc.h"
PreviewProcess::PreviewProcess(const Scene *scene, int sceneResID, int blockSize)
: m_vpl(NULL) {
m_blockSize = blockSize;
m_logLevel = ETrace;
m_mutex = new Mutex();
m_scene = scene;
m_film = m_scene->getFilm();
bindResource("scene", sceneResID);
}
bool PreviewProcess::isLocal() const {
return true;
}
void PreviewProcess::processResult(const WorkResult *result, bool cancelled) {
const ImageBlock *block = static_cast(result);
const int sx = block->getOffset().x - m_film->getCropOffset().x,
sy = block->getOffset().y - m_film->getCropOffset().y;
const int ex = sx + block->getSize().x, ey = sy + block->getSize().y;
int pos = 0;
Float r=0, g=0, b=0;
if (m_source) {
for (int y=sy; ygetFloatData() + ((m_target->getHeight() - 1 - y) * m_source->getWidth() + sx) * 3;
float *target = m_target->getFloatData() + ((m_target->getHeight() - 1 - y)
* m_target->getWidth() + sx) * 3;
for (int x=sx; xgetPixel(pos++).toLinearRGB(r, g, b);
*target++ = (float) (r + *source++);
*target++ = (float) (g + *source++);
*target++ = (float) (b + *source++);
}
}
} else {
for (int y=sy; ygetFloatData() + ((m_target->getHeight() - 1 - y)
* m_target->getWidth() + sx) * 3;
for (int x=sx; xgetPixel(pos++).toLinearRGB(r, g, b);
*target++ = (float) r;
*target++ = (float) g;
*target++ = (float) b;
}
}
}
m_mutex->lock();
m_numRays += block->getExtra();
m_mutex->unlock();
}
void PreviewProcess::configure(const VPL &vpl, Float minDist, const Point2 &jitter,
const Bitmap *source, Bitmap *target, bool coherent, bool diffuseSources,
bool diffuseReceivers) {
BlockedImageProcess::init(m_film->getCropOffset(), m_film->getCropSize(), m_blockSize);
m_source = source;
m_target = target;
m_numRays = 0;
m_vpl = &vpl;
m_minDist = minDist;
m_coherent = coherent;
m_diffuseSources = diffuseSources;
m_diffuseReceivers = diffuseReceivers;
/* It is not necessary to shoot normalized rays. Instead, interpolate:
here, we generate the upper left corner ray as well as the
per-pixel increments */
Ray topLeftRay, rightRay, bottomRay;
const Point2 topLeft(jitter);
const Point2 right(topLeft.x + m_film->getSize().x, topLeft.y);
const Point2 bottom(topLeft.x, topLeft.y + m_film->getSize().y);
const Point2 lens(0, 0);
Float time = 0.0f;
const Camera *camera = m_scene->getCamera();
camera->generateRay(topLeft, lens, time, topLeftRay);
camera->generateRay(right, lens, time, rightRay);
camera->generateRay(bottom, lens, time, bottomRay);
m_cameraTL = Vector(topLeftRay.d);
m_cameraO = camera->getPosition();
m_cameraDx = (rightRay.d - topLeftRay.d)
/ (Float) m_film->getSize().x;
m_cameraDy = (bottomRay.d - topLeftRay.d)
/ (Float) m_film->getSize().y;
}
ref PreviewProcess::createWorkProcessor() const {
return new PreviewWorker(m_blockSize, m_cameraO, m_cameraTL,
m_cameraDx, m_cameraDy, *m_vpl, m_minDist, m_coherent,
m_diffuseSources, m_diffuseReceivers);
}
MTS_IMPLEMENT_CLASS(PreviewProcess, false, BlockedImageProcess)