void TrackMarker::setKeyFrameOnCenterAndPatternAtTime(int time) { KnobDoublePtr center = _imp->center.lock(); for (int i = 0; i < center->getDimension(); ++i) { double v = center->getValueAtTime(time, i); center->setValueAtTime(time, v, ViewSpec::all(), i); } KnobDoublePtr patternCorners[4] = {_imp->patternBtmLeft.lock(), _imp->patternTopLeft.lock(), _imp->patternTopRight.lock(), _imp->patternBtmRight.lock()}; for (int c = 0; c < 4; ++c) { KnobDoublePtr k = patternCorners[c]; for (int i = 0; i < k->getDimension(); ++i) { double v = k->getValueAtTime(time, i); k->setValueAtTime(time, v, ViewSpec::all(), i); } } }
TEST_F(BaseTest, SetValues) { NodePtr generator = createNode(_generatorPluginID); assert(generator); KnobIPtr knob = generator->getKnobByName("noiseZSlope"); KnobDoublePtr radius = boost::dynamic_pointer_cast<KnobDouble>(knob); EXPECT_TRUE(radius != 0); if (!radius) { return; } radius->setValue(0.5); EXPECT_TRUE(radius->getValue() == 0.5); //Check that linear interpolation is working as intended KeyFrame kf; radius->setInterpolationAtTime(eCurveChangeReasonInternal, ViewSpec::all(), 0, 0, eKeyframeTypeLinear, &kf); radius->setValueAtTime(0, 0., ViewSpec::all(), 0); radius->setValueAtTime(100, 1., ViewSpec::all(), 0); for (int i = 0; i <= 100; ++i) { double v = radius->getValueAtTime(i); EXPECT_TRUE(std::abs(v - i / 100.) < 1e-6); } }
bool TrackMarkerPM::trackMarker(bool forward, int refFrame, int frame) { KnobButtonPtr button; if (forward) { button = trackNextButton.lock(); } else { button = trackPrevButton.lock(); } KnobIntPtr refFrameK = refFrameKnob.lock(); refFrameK->setValue(refFrame); // Unslave the center knob since the trackerNode will update it, then update the marker center KnobDoublePtr center = centerKnob.lock(); center->unlink(DimSpec::all(), ViewSetSpec::all(), true); trackerNode->getEffectInstance()->onKnobValueChanged_public(button, eValueChangedReasonUserEdited, TimeValue(frame), ViewIdx(0)); KnobDoublePtr markerCenter = getCenterKnob(); // The TrackerPM plug-in has set a keyframe at the refFrame and frame, copy them bool ret = true; double centerPoint[2]; for (int i = 0; i < center->getNDimensions(); ++i) { { int index = center->getKeyFrameIndex(ViewIdx(0), DimIdx(i), TimeValue(frame)); if (index != -1) { centerPoint[i] = center->getValueAtTime(TimeValue(frame), DimIdx(i)); markerCenter->setValueAtTime(TimeValue(frame), centerPoint[i], ViewSetSpec::all(), DimIdx(i)); } else { // No keyframe at this time: tracking failed ret = false; break; } } { int index = center->getKeyFrameIndex(ViewIdx(0), DimIdx(i), TimeValue(refFrame)); if (index != -1) { double value = center->getValueAtTime(TimeValue(refFrame), DimIdx(i)); markerCenter->setValueAtTime(TimeValue(refFrame), value, ViewSetSpec::all(), DimIdx(i)); } } } // Convert the correlation score of the TrackerPM to the error if (ret) { KnobDoublePtr markerError = getErrorKnob(); KnobDoublePtr correlation = correlationScoreKnob.lock(); { int index = correlation->getKeyFrameIndex(ViewIdx(0), DimIdx(0), TimeValue(frame)); if (index != -1) { // The error is estimated as a percentage of the correlation across the number of pixels in the pattern window KnobDoublePtr pBtmLeft = patternBtmLeftKnob.lock(); KnobDoublePtr pTopRight = patternTopRightKnob.lock(); Point btmLeft, topRight; btmLeft.x = pBtmLeft->getValueAtTime(TimeValue(frame), DimIdx(0)); btmLeft.y = pBtmLeft->getValueAtTime(TimeValue(frame), DimIdx(1)); topRight.x = pTopRight->getValueAtTime(TimeValue(frame), DimIdx(0)); topRight.y = pTopRight->getValueAtTime(TimeValue(frame), DimIdx(1)); double areaPixels = (topRight.x - btmLeft.x) * (topRight.y - btmLeft.y); NodePtr trackerInput = trackerNode->getInput(0); if (trackerInput) { ImagePlaneDesc comps, paireComps; trackerInput->getEffectInstance()->getMetadataComponents(-1, &comps, &paireComps); areaPixels *= comps.getNumComponents(); } double value = correlation->getValueAtTime(TimeValue(frame), DimIdx(0)); // Convert to a percentage if (areaPixels > 0) { value /= areaPixels; } markerError->setValueAtTime(TimeValue(frame), value, ViewSetSpec::all(), DimIdx(0)); } } } if ( !center->linkTo(markerCenter) ) { throw std::runtime_error("Could not link center"); } return ret; } // TrackMarkerPM::trackMarker
bool TrackMarkerPM::trackMarker(bool forward, int refFrame, int frame) { KnobButtonPtr button; if (forward) { button = trackNextButton.lock(); } else { button = trackPrevButton.lock(); } KnobIntPtr refFrameK = refFrameKnob.lock(); refFrameK->setValue(refFrame); // Unslave the center knob since the trackerNode will update it, then update the marker center KnobDoublePtr center = centerKnob.lock(); for (int i = 0; i < center->getDimension(); ++i) { center->unSlave(i, true); } trackerNode->getEffectInstance()->onKnobValueChanged_public(button, eValueChangedReasonNatronInternalEdited, frame, ViewIdx(0), true); KnobDoublePtr markerCenter = getCenterKnob(); // The TrackerPM plug-in has set a keyframe at the refFrame and frame, copy them bool ret = true; double centerPoint[2]; for (int i = 0; i < center->getDimension(); ++i) { { int index = center->getKeyFrameIndex(ViewSpec::current(), i, frame); if (index != -1) { centerPoint[i] = center->getValueAtTime(frame, i); markerCenter->setValueAtTime(frame, centerPoint[i], ViewSpec::current(), i); } else { // No keyframe at this time: tracking failed ret = false; break; } } { int index = center->getKeyFrameIndex(ViewSpec::current(), i, refFrame); if (index != -1) { double value = center->getValueAtTime(refFrame, i); markerCenter->setValueAtTime(refFrame, value, ViewSpec::current(), i); } } } // Convert the correlation score of the TrackerPM to the error if (ret) { KnobDoublePtr markerError = getErrorKnob(); KnobDoublePtr correlation = correlationScoreKnob.lock(); { int index = correlation->getKeyFrameIndex(ViewSpec::current(), 0, frame); if (index != -1) { // The error is estimated as a percentage of the correlation across the number of pixels in the pattern window KnobDoublePtr pBtmLeft = patternBtmLeftKnob.lock(); KnobDoublePtr pTopRight = patternTopRightKnob.lock(); Point btmLeft, topRight; btmLeft.x = pBtmLeft->getValueAtTime(frame, 0); btmLeft.y = pBtmLeft->getValueAtTime(frame, 1); topRight.x = pTopRight->getValueAtTime(frame, 0); topRight.y = pTopRight->getValueAtTime(frame, 1); double areaPixels = (topRight.x - btmLeft.x) * (topRight.y - btmLeft.y); NodePtr trackerInput = trackerNode->getInput(0); if (trackerInput) { ImageComponents comps = trackerInput->getEffectInstance()->getComponents(-1); areaPixels *= comps.getNumComponents(); } double value = correlation->getValueAtTime(frame, 0); // Convert to a percentage value /= areaPixels; markerError->setValueAtTime(frame, value, ViewSpec::current(), 0); } } } for (int i = 0; i < center->getDimension(); ++i) { center->slaveTo(i, markerCenter, i); } return ret; } // TrackMarkerPM::trackMarker