void Context::Camera(const string &n, const ParamSet ¶ms) { VERIFY_OPTIONS("Camera"); renderFarm->send("luxCamera", n, params); renderOptions->cameraName = n; renderOptions->cameraParams = params; MotionTransform cameraTransform = curTransform; string endTransformName = renderOptions->cameraParams.FindOneString("endtransform", ""); if (namedCoordinateSystems.find(endTransformName) != namedCoordinateSystems.end()) { if (curTransform.IsStatic()) { lux::Transform endTransform = namedCoordinateSystems[endTransformName].StaticTransform(); // this isn't pretty, but it'll have to do until we can fully deprecate it vector<float> times; times.push_back(renderOptions->cameraParams.FindOneFloat("shutteropen", 0.f)); times.push_back(renderOptions->cameraParams.FindOneFloat("shutterclose", 1.f)); vector<lux::Transform> transforms; transforms.push_back(curTransform.StaticTransform()); transforms.push_back(endTransform); cameraTransform = MotionTransform(times, transforms); } else { LOG(LUX_WARNING, LUX_CONSISTENCY) << "Both motion transform and endtransform specified for camera, ignoring endtransform"; } } else if (endTransformName != "") { LOG(LUX_WARNING, LUX_CONSISTENCY) << "Invalid endtransform name for camera: '" << endTransformName << "'"; } renderOptions->worldToCamera = cameraTransform; namedCoordinateSystems["camera"] = cameraTransform.GetInverse(); }
void Context::CoordSysTransform(const string &n) { VERIFY_INITIALIZED_TRANSFORMS("CoordSysTransform"); renderFarm->send("luxCoordSysTransform", n); if (namedCoordinateSystems.find(n) != namedCoordinateSystems.end()) { MotionTransform mt = namedCoordinateSystems[n]; if (inMotionBlock) { if (mt.IsStatic()) motionBlockTransforms.push_back(mt.StaticTransform()); else { LOG(LUX_ERROR,LUX_NESTING) << "Cannot use motion coordinate system '" << n << "' inside Motion block, ignoring."; } } else{ curTransform = mt; } } else { LOG(LUX_ERROR,LUX_SYNTAX) << "Coordinate system '" << n << "' unknown"; } }
// Concantenates two MotionTransforms. // Extract the unique knots from input MotionTransform // for each unique knot interpolate the knots from the other MotionTransform and concantenate. // Thus if left hand has knots at (1, 3) and right hand has knots at (1, 4) then output has // knots at (1, 3, 4) where right hand side has been interpolated at knot t=3 and left hand side // is kept constant after t=3. MotionTransform MotionTransform::operator*(const MotionTransform &t) const { BOOST_ASSERT(Valid()); BOOST_ASSERT(t.Valid()); if (IsStatic() && t.IsStatic()) return MotionTransform(transforms.front() * t.transforms.front()); vector<float> new_times(times.size() + t.times.size()); vector<Transform> new_transforms; // remove duplicates size_t new_size = std::set_union(times.begin(), times.end(), t.times.begin(), t.times.end(), new_times.begin()) - new_times.begin(); new_times.resize(new_size); typedef vector<float>::const_iterator time_cit; typedef vector<Transform>::iterator trans_it; typedef vector<Transform>::const_iterator trans_cit; // used so we have valid time iterators in case either is static vector<float> time_zero(1, 0.f); // left side's times and transforms time_cit timeL = IsStatic() ? time_zero.begin() : times.begin(); time_cit timeEndL = IsStatic() ? time_zero.end() : times.end(); trans_cit transL = transforms.begin(); time_cit prev_timeL = timeL; trans_cit prev_transL = transL; // right side's times and transforms time_cit timeR = IsStatic() ? time_zero.begin() : t.times.begin(); time_cit timeEndR = IsStatic() ? time_zero.end() : t.times.end(); trans_cit transR = t.transforms.begin(); time_cit prev_timeR = timeR; trans_cit prev_transR = transR; // motion systems interpolating left side knots InterpolatedTransform itL(*prev_timeL, *timeL, *prev_transL, *transL); // motion systems interpolating right side knots InterpolatedTransform itR(*prev_timeR, *timeR, *prev_transR, *transR); // loop over unique knots for (time_cit timeN = new_times.begin(); timeN != new_times.end(); timeN++) { if (*timeL <= *timeN) { // need to move to next knot prev_timeL = timeL; timeL = min(timeL+1, timeEndL-1); prev_transL = transL; transL = min(transL+1, transforms.end()-1); // update for interpolation itL = InterpolatedTransform(*prev_timeL, *timeL, *prev_transL, *transL); } if (*timeR <= *timeN) { // need to move to next knot prev_timeR = timeR; timeR = min(timeR+1, timeEndR-1); prev_transR = transR; transR = min(transR+1, t.transforms.end()-1); // update for interpolation itR = InterpolatedTransform(*prev_timeR, *timeR, *prev_transR, *transR); } // get (possibly interpolated) left and right hand values at new knot Transform tL = itL.Sample(*timeN); Transform tR = itR.Sample(*timeN); // append the concantenated result new_transforms.push_back(tL * tR); } return MotionTransform(new_times, new_transforms); }