예제 #1
0
	void print_if_too_large(const Vector3 & update, const std::string & name) {
		if (update.array().abs().maxCoeff() > M_PI / 4) {
			std::cout << "[" << iteration << "]" << name
					<< " has too large elements " << std::endl
					<< update.transpose() << std::endl;
		}
	}
예제 #2
0
QVector<Eigen::AlignedBox3d> splitBox( const Eigen::AlignedBox3d & box, Vector3 axis )
{
	Eigen::AlignedBox3d b1 = box, b2 = box;
	Vector3 delta = axis.array() * ((box.sizes() * 0.5).array());
	return QVector<Eigen::AlignedBox3d>() << box.intersection(b1.translate(-delta)) <<
		box.intersection(b2.translate(delta));
}
예제 #3
0
void Phong::shadePhoton(const Ray &ray, const HitInfo &rhit, const Scene &scene, Vector3 const &power, Photon_map *map) const
{
    HitInfo hit = bumpHit(rhit);
    Vector3 dcolor = m_kd * m_texture_kd->shade(ray, hit, scene);
    if (dcolor.max() > EPSILON && (!map->isCaustics() || ray.seen_specular))
    {
        Vector3 const &position = hit.P;
        Vector3 powe = power * dcolor;
        Vector3 const &dir = ray.d;
        map->store(powe.array(), position.array(), dir.array());
    }
    if (ray.iter > MAX_RAY_ITER) 
		return;
    Vector3 scolor = m_ks * m_texture_ks->shade(ray, hit, scene);
    Vector3 total_color = dcolor + scolor;
    float pr = total_color.max();
    float pd = pr * dcolor.sum() / total_color.sum();
    float ps = pr - pd;
    float pspec_refr = m_tp * ps;
    float pspec_refl = ps - pspec_refr;

    Vector3 *color = 0;
    float probability = -1;
    Ray r;
    r.refractionIndex = ray.refractionIndex;
    r.refractionStack = ray.refractionStack;
    r.iter = ray.iter + 1;
    r.o = hit.P;
    r.seen_specular = ray.seen_specular;
    Vector3 randvect(randone(g_rng), randone(g_rng), randone(g_rng));
    float russian_roulette = randone(g_rng);
    if (russian_roulette < pd)
    {
        if (map->isCaustics()) return;
        color = &dcolor;
        probability = pd;
        float theta = asinf((randone(g_rng)));
        float phi = 2 * PI * randone(g_rng);

        Vector3 const &yaxis = hit.N;
        Vector3 xaxis = yaxis.cross(randvect);
        xaxis.normalize();
        Vector3 zaxis = yaxis.cross(xaxis);
        zaxis.normalize();
        r.d = 0;
        r.d += sinf(theta) * cosf(phi) * xaxis;
        r.d += sinf(theta) * sinf(phi) * zaxis;
        r.d += cosf(theta) * yaxis;
        r.d.normalize();
    }
    else if (russian_roulette < pd + pspec_refl)
    {
        probability = pspec_refl;
        color = &scolor;
        if (m_is_glossy)
        {
            Vector3 R = ray.d - 2 * ray.d.dot(hit.N) * hit.N;

            Vector3 u = R.cross(randvect);
            u.normalize();
            Vector3 v = R.cross(u);
            v.normalize();

            float theta = acos(powf(1.0f - randone(g_rng), (1.0f / (m_phong + 1))));
            float phi = 2.0f * PI * randone(g_rng);

            r.d = 0;
            r.d += sinf(theta) * cosf(phi) * u;
            r.d += sinf(theta) * sinf(phi) * v;
            r.d += cosf(theta) * R;
        }
        else
            r.d = ray.d - 2*ray.d.dot(hit.N)*hit.N;
        r.seen_specular = true;
    }
    else if (russian_roulette < pr)
    {
        probability = pspec_refr;
        color = &scolor;
        float ratio = 1.0;
		if ((*ray.refractionStack)[ray.refractionIndex] == m_refr && m_refr != 1.0)
        {
            r.refractionIndex = ray.refractionIndex - 1;
            ratio = m_refr / (*r.refractionStack)[r.refractionIndex];
        }
        else if ((*ray.refractionStack)[ray.refractionIndex] != m_refr)
        {
            r.refractionIndex = ray.refractionIndex + 1;
            r.refractionStack->push_back(m_refr);
            ratio = (*ray.refractionStack)[ray.refractionIndex] / m_refr;
        }
        Vector3 w = -ray.d;
        float dDotN = w.dot(hit.N);
        if (dDotN < 0)
            dDotN = -dDotN;
        if (1 - ratio*ratio*(1 - dDotN*dDotN) < 0)
            return;
        r.d = -ratio * (w - dDotN*hit.N) - sqrtf(1 - ratio*ratio*(1 - dDotN*dDotN)) * hit.N;
        r.d.normalize();
        r.seen_specular = true;
    }
    else
        return;

    HitInfo h;
    if (scene.trace(h, r, EPSILON))
    {
        h.material->shadePhoton(r, h, scene, power * *color / probability, map);
    }
}
예제 #4
0
SliceChunk PartCorresponder::mergeChunks(const QVector<SliceChunk> & chunks, ParticleMesh * input, Particles & particles)
{
	SliceChunk chunk;
	if(chunks.empty()) return chunk;
	if(chunks.size() == 1) return chunks.front();

	// Combine graphs - is it needed?
	if( false ){
		for(auto & c : chunks){
			for(auto v : c.g.vertices) chunk.g.AddVertex(v);
			for(auto e : c.g.GetEdgesSet()) chunk.g.AddEdge(e.index, e.target, 1);
		}
	}

	// Remove gaps between chunks
	QVector<Vector3> packedPoints;

	// Decide if we will allow moves along 'x' or 'y'
	Vector3 diagonal = chunks.back().box.center() - chunks.front().box.center();
	diagonal = diagonal.cwiseAbs().normalized();
	if(diagonal[0] > diagonal[1]) diagonal = Vector3(1,0,0);
	else diagonal = Vector3(0,1,0);

	Vector3 halfVoxel(input->grid.unitlength,input->grid.unitlength,input->grid.unitlength);
	halfVoxel *= 0.5;

	// Initial start
	Vector3 delta = chunks.front().box.min();

	// Snap chunks to each other
	for(size_t ci = 0; ci < chunks.size(); ci++)
	{
		for(auto v : chunks[ci].g.vertices)
		{
			auto p = particles[v].pos - delta;
			packedPoints.push_back( p );

			chunk.box.extend( p + halfVoxel );
			chunk.box.extend( p - halfVoxel );

			// Save mapped index
			chunk.vmap.push_back( v );
		}

		if(ci+1 == chunks.size()) continue;

		Vector3 d = chunk.box.diagonal().array() * diagonal.array();
		delta = chunks[ci+1].box.min() - d;
	}

	// Compute index of relative particle positions inside box
	chunk.tree = QSharedPointer<NanoKdTree>(new NanoKdTree);
	for(size_t i = 0; i < packedPoints.size(); i++)
	{
		Vector3 relativePos = (packedPoints[i] - chunk.box.min()).array() / chunk.box.sizes().array();
		chunk.tree->addPoint( relativePos );
		particles[chunk.vmap[i]].relativePos = relativePos;
	}
	chunk.tree->build();

	return chunk;
}