Esempio n. 1
0
 bool VisObj::select_vertex(const CGLA::Vec2i& pos)
 {
     float d;
     if(depth_pick(pos[0], pos[1], d))
     {
         Vec3d c;
         float r;
         bsphere(mani, c, r);
         VertexID closest = InvalidVertexID;
         double min_dist = DBL_MAX;
         for(auto vid : mani.vertices())
         {
             Vec3d wp = world2screen(mani.pos(vid));
             if(sqr_length(Vec2d(wp[0],wp[1])-Vec2d(pos))<100)
             {
                 double dist = sqr_length(screen2world(pos[0], pos[1], d)-mani.pos(vid));
                 if(dist < min_dist)
                 {
                     min_dist = dist;
                     closest = vid;
                 }
             }
         }
         if(closest != InvalidVertexID) {
             vertex_selection.resize(mani.allocated_vertices(),0);
             vertex_selection[closest] = !vertex_selection[closest];
             active_selection = true;
             post_create_display_list();
             return true;
         }
     }
     return false;
     
 }
Esempio n. 2
0
 void VisObj::refit()
 {
     bsphere(mani, bsphere_center, bsphere_radius);
     
     view_ctrl.set_centre(Vec3f(bsphere_center));
     view_ctrl.set_eye_dist(2*bsphere_radius);
 }
Esempio n. 3
0
void VPLShaderManager::setVPL(const VPL &vpl) {
	const size_t sampleCount = 250;

	/* Estimate good near and far plane locations by tracing some rays */
	m_nearClip =  std::numeric_limits<Float>::infinity();
	m_farClip  = -std::numeric_limits<Float>::infinity();

	/* Update animations */
	for (size_t i=0; i<m_animatedGeometry.size(); ++i) {
		const AnimatedGeometryRecord &agRec = m_animatedGeometry[i];
		const Matrix4x4 &matrix = agRec.trafo->eval(vpl.its.time).getMatrix();

		if (agRec.geometryIndex >= 0)
			m_geometry[agRec.geometryIndex].second = matrix;

		if (agRec.opaqueGeometryIndex >= 0)
			m_opaqueGeometry[agRec.opaqueGeometryIndex].second = matrix;
	}

	if (vpl.type != EDirectionalEmitterVPL) {
		/* Trace a few rays from the VPL to estimate a suitable depth range */
		for (size_t i=0; i<sampleCount; ++i) {
			Point2 sample = sample02(i);

			Ray ray;
			if (vpl.type == ESurfaceVPL || (vpl.type == EPointEmitterVPL &&
						vpl.emitter->getType() & Emitter::EOnSurface)) {
				ray = Ray(vpl.its.p, vpl.its.shFrame.toWorld(
							warp::squareToCosineHemisphere(sample)), 0);

				#if defined(MTS_VPL_USE_PARABOLOID_MAPS)
					m_shadowMapType = ShadowMapGenerator::EParaboloid;
				#elif defined(MTS_VPL_USE_SINGLE_PASS)
					m_shadowMapType = ShadowMapGenerator::EHemicubeSinglePass;
				#else
					m_shadowMapType = ShadowMapGenerator::EHemicube;
				#endif
			} else if (vpl.type == EPointEmitterVPL) {
				ray = Ray(vpl.its.p, warp::squareToUniformSphere(sample), 0);
				#if defined(MTS_VPL_USE_SINGLE_PASS)
					m_shadowMapType = ShadowMapGenerator::ECubeSinglePass;
				#else
					m_shadowMapType = ShadowMapGenerator::ECube;
				#endif
			} else {
				Log(EError, "Unsupported VPL type!");
			}

			ConstShapePtr shape; Normal n; Point2 uv; /* unused */
			Float t, accum = 0;
			bool hit = false;

			for (int it=0; it<5; ++it) {
				if (!m_scene->rayIntersect(ray, t, shape, n, uv))
					break;

				accum += t;
				if (!(shape->getBSDF()->getType() & BSDF::ETransmission)) {
					hit = true;
					break;
				}

				ray.o = ray(t);
			}

			if (hit && accum > 0) {
				m_nearClip = std::min(m_nearClip, accum);
				m_farClip = std::max(m_farClip, accum);
			}
		}

		if (m_nearClip >= m_farClip) {
			BSphere bsphere(m_scene->getKDTree()->getAABB().getBSphere());
			Float minDist = 0;

			if ((vpl.type == ESurfaceVPL || vpl.type == EPointEmitterVPL) &&
					!bsphere.contains(vpl.its.p))
				minDist = (bsphere.center - vpl.its.p).length() - bsphere.radius;

			/* If everything fails, use really conservative bounds */
			m_farClip = minDist + bsphere.radius * 2.25f;
			m_nearClip = std::max(minDist - 0.25f * bsphere.radius, m_farClip * 1e-5f);
		} else {
			m_nearClip = std::max(m_nearClip / 1.5f, m_farClip * 1e-5f);
			m_farClip *= 1.5f;
		}

		m_shadowMapTransform =
			(Transform::translate(Vector(vpl.its.p)) *
			Transform::fromFrame(vpl.its.shFrame)).inverse();
	} else {
		m_shadowMapType = ShadowMapGenerator::EDirectional;
		m_shadowMapTransform = m_shadowGen->directionalFindGoodFrame(
			m_scene->getKDTree()->getAABB(), vpl.its.shFrame.n);
	}

	bool is2D =
		m_shadowMapType == ShadowMapGenerator::EParaboloid ||
		m_shadowMapType == ShadowMapGenerator::EDirectional;

	if (is2D) {
		if (!m_shadowMap2D || m_shadowMap2D->getSize().x != m_shadowMapResolution) {
			if (m_shadowMap2D)
				m_shadowMap2D->cleanup();
			m_shadowMap2D = m_shadowGen->allocate(m_renderer,
				m_shadowMapType, m_shadowMapResolution);
		}
		m_shadowMap = m_shadowMap2D;
	} else {
		if (!m_shadowMapCube || m_shadowMapCube->getSize().x != m_shadowMapResolution) {
			if (m_shadowMapCube)
				m_shadowMapCube->cleanup();
			m_shadowMapCube = m_shadowGen->allocate(m_renderer,
				m_shadowMapType, m_shadowMapResolution);
		}
		m_shadowMap = m_shadowMapCube;
	}

	Float sample = sampleTEAFloat(m_vplIndex++, 0x12345);
	m_shadowGen->render(m_renderer, m_shadowMap, m_shadowMapType,
			m_shadowMapTransform, m_nearClip, m_farClip,
			sample > 0.3 ? m_opaqueGeometry : m_geometry);

	/* Convert between the Mitsuba and OpenGL matrix conventions */
	m_shadowMapTransform = Transform::scale(
		Vector(-1.0f, 1.0f, -1.0f)) * m_shadowMapTransform;
}