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; } }
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)); }
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); } }
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; }