void PointLightInteractionHandler::setLightPosFromScreenCoords(const vec2& normalizedScreenCoord) { vec2 deviceCoord(2.f * (normalizedScreenCoord - 0.5f)); // Flip vertical axis since mouse event y position starts at top of screen deviceCoord.y *= -1.f; // Use half distance between look from and look to positions as scene radius. float sceneRadius = 0.5f * glm::length(camera_->getLookTo() - camera_->getLookFrom()); vec3 rayOrigin = camera_->getWorldPosFromNormalizedDeviceCoords(vec3(deviceCoord, 0.f)); vec3 rayDir = glm::normalize( camera_->getWorldPosFromNormalizedDeviceCoords(vec3(deviceCoord, 1.f)) - rayOrigin); float t0 = 0, t1 = std::numeric_limits<float>::max(); float lightRadius = glm::length(lightPosition_->get()); if (raySphereIntersection(vec3(0.f), sceneRadius, rayOrigin, rayDir, &t0, &t1)) { lightPosition_->set(glm::normalize(rayOrigin + t1 * rayDir) * lightRadius); } else { // Project it to the rim of the sphere t0 = 0; t1 = std::numeric_limits<float>::max(); if (rayPlaneIntersection(camera_->getLookTo(), glm::normalize(camera_->getLookTo() - camera_->getLookFrom()), rayOrigin, rayDir, &t0, &t1)) { // Project it to the edge of the sphere lightPosition_->set(glm::normalize(rayOrigin + t1 * rayDir) * lightRadius); } } // Ensure that up vector is same as camera afterwards setLookUp(camera_->getLookUp()); }
void PointLightInteractionHandler::onCameraChanged() { // This makes sure that the interaction with the light source is consistent with the direction // of the camera setLookUp(camera_->getLookUp()); }
void CameraProperty::setLook(vec3 lookFrom, vec3 lookTo, vec3 lookUp) { NetworkLock lock(this); setLookFrom(lookFrom); setLookTo(lookTo); setLookUp(lookUp); }