void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { if (nlhs != 1 || nrhs < 3) { mexErrMsgTxt("Usage: [afValues] = fndllFastInterp2(a2Image, Cols (Nx1),Rows (Nx1), NaN value (optional))"); return; } float NaNValue = 0; if (nrhs == 4) { double *pNaNValue = (double *)mxGetData(prhs[3]); NaNValue = *pNaNValue; } /* Get the number of dimensions in the input argument. */ if (mxGetNumberOfDimensions(prhs[0]) != 2) { mexErrMsgTxt("Input volume must be 2D. "); return; } const int *input_dim_array = mxGetDimensions(prhs[0]); int in_rows = input_dim_array[0]; int in_cols = input_dim_array[1]; double *rows = (double *)mxGetData(prhs[2]); double *cols = (double *)mxGetData(prhs[1]); const int *tmp = mxGetDimensions(prhs[1]); int iNumPoints = MAX(tmp[0], tmp[1]); int output_dim_array[2]; output_dim_array[0] = iNumPoints; output_dim_array[1] = 1; plhs[0] = mxCreateNumericArray(2, output_dim_array, mxSINGLE_CLASS, mxREAL); float *output_vector = (float*)mxGetPr(plhs[0]); if (mxIsSingle(prhs[0])) { float *input_image = (float*)mxGetData(prhs[0]); CalcInterpolation(input_image, output_vector,iNumPoints, rows, cols, in_rows,in_cols,NaNValue); } if (mxIsDouble(prhs[0])) { double *input_image = (double*)mxGetData(prhs[0]); CalcInterpolation(input_image, output_vector,iNumPoints, rows, cols, in_rows,in_cols,NaNValue); } if (mxIsUint16(prhs[0]) || mxIsInt16(prhs[0])) { short *input_image = (short*)mxGetData(prhs[0]); CalcInterpolation(input_image, output_vector,iNumPoints, rows, cols, in_rows,in_cols,NaNValue); } if (mxIsUint8(prhs[0])) { unsigned char *input_image = (unsigned char *)mxGetData(prhs[0]); CalcInterpolation(input_image, output_vector,iNumPoints, rows, cols,in_rows,in_cols,NaNValue); } }
void XLayerMove::FrameMove( XSprObj *pSprObj, float dt, float fFrmCurr ) { // 좌표 보간 if( m_cnPos.interpolation ) // 보간이동중이다 { XKeyPos *pStartKey = m_cnPos.pStartKey; XKeyPos *pEndKey = m_cnPos.pEndKey; XBREAK( pStartKey == NULL ); XBREAK( pEndKey == NULL ); float fInterLength = pEndKey->GetfFrame() - pStartKey->GetfFrame(); // 보간구간의 전체 길이 float fTimeLerp = (fFrmCurr - pStartKey->GetfFrame()) / fInterLength; // 전체 보간구간중 현재 플레잉중인 프레임의 위치(0~1) // 패스의 끝까지 왔다 if( fTimeLerp >= 1.0f ) fTimeLerp = 1.0f; // 속도보간 float fSpeedLerp = 0; CalcInterpolation( &fSpeedLerp, fTimeLerp, m_cnPos.interpolation ); // 속도보간값에 따른 패스상의 현재 위치 // fSpeedLerp값이 전체패스상에서 어느위치인지 계산 switch( m_cnPos.typePath ) { case SPR::xLINE_LINE: { if( pStartKey->GetpInterpolationEndKey() == pStartKey->GetpNextPathKey() ) // 보간끝키가 다음키와 같다면 단칸패스이므로 기존과 같이 계산 { // 단칸구간 XE::VEC2 v1 = pStartKey->GetPos(); XE::VEC2 v2 = pEndKey->GetPos(); m_cnPos.vPos = v1 + (v2 - v1) * fSpeedLerp; // 최종좌표 } else { XBREAK( pStartKey->GetpNextPathKey() == NULL ); // fSlerp가 어느키 구간에 걸려있는지 탐색 XKeyPos *pCurrKey = pStartKey; float keyLerp=0, nextKeyLerp=0; while(1) { keyLerp = (pCurrKey->GetfFrame() - pStartKey->GetfFrame()) / fInterLength; // 전체 보간구간에서의 현재키lerp값 nextKeyLerp = (pCurrKey->GetpNextPathKey()->GetfFrame() - pStartKey->GetfFrame()) / fInterLength; // 다음키의 전체보간구간에서의 lerp값 if( fSpeedLerp < nextKeyLerp ) break; pCurrKey = pCurrKey->GetpNextPathKey(); } // pCurrKey ~ pNextKey구간을 0~1로 보고 fSlerp가 그중 어느위치인지 계산 { float fLerp = (fSpeedLerp - keyLerp) / (nextKeyLerp - keyLerp); // 키구간사이에서의 lerp값 XE::VEC2 v1 = pCurrKey->GetPos(); XE::VEC2 v2 = pCurrKey->GetpNextPathKey()->GetPos(); m_cnPos.vPos = v1 + (v2 - v1) * fLerp; // 최종좌표 } } } break; case SPR::xLINE_SPLINE_CATMULLROM: { XE::VEC2 v0, v1, v2, v3, vOut; float fLerp = fSpeedLerp; // 스플라인보간값을 계산하기위해 v0, v1, v2, v3좌표를 얻는다 if( pStartKey->GetpNextPathKey() ) // 시작키의 다음키가 없으면 보간하지 않음 { if( pStartKey->GetpInterpolationEndKey() == pStartKey->GetpNextPathKey() ) { // 스플라인타입인데 단칸짜리 v0 = ( pStartKey->GetpPrevPathKey() )? pStartKey->GetpPrevPathKey()->GetPos() : pStartKey->GetPos(); v1 = pStartKey->GetPos(); v2 = pEndKey->GetPos(); v3 = ( pEndKey->GetpNextPathKey() )? pEndKey->GetpNextPathKey()->GetPos() : pEndKey->GetPos(); } else { // 스플라인타입 다구간 보간 // 현재 fSpeedLerp가 스플라인구간중에서 어느구간인지 찾아낸다 XKeyPos *pCurrKey = pStartKey; float keyLerp=0, nextKeyLerp=0; while(1) { if( XBREAK( pCurrKey->GetpNextPathKey() == NULL ) ) break; keyLerp = (pCurrKey->GetfFrame() - pStartKey->GetfFrame()) / fInterLength; // 전체 보간구간에서의 현재키lerp값 nextKeyLerp = (pCurrKey->GetpNextPathKey()->GetfFrame() - pStartKey->GetfFrame()) / fInterLength; // 다음키의 전체보간구간에서의 lerp값 if( fSpeedLerp <= nextKeyLerp ) break; pCurrKey = pCurrKey->GetpNextPathKey(); } // pCurrKey ~ pNextKey구간을 0~1로 보고 fSpeedLerp가 그중 어느위치인지 계산 { fLerp = (fSpeedLerp - keyLerp) / (nextKeyLerp - keyLerp); // 키구간사이에서의 lerp값 v0 = ( pCurrKey->GetpPrevPathKey() )? pCurrKey->GetpPrevPathKey()->GetPos() : pCurrKey->GetPos(); v1 = pCurrKey->GetPos(); v2 = ( pCurrKey->GetpNextPathKey() )? pCurrKey->GetpNextPathKey()->GetPos() : pCurrKey->GetPos(); if( pCurrKey->GetpNextPathKey() ) { // if( pCurrKey->GetpNextPathKey()->GetpNextPathKey( pCurrKey->GetidPath() ) ) if( pCurrKey->GetpNextPathKey()->GetpNextPathKey() && pCurrKey->GetpNextPathKey()->GetpNextPathKey()->GetpPrevPathKey() ) // 다다음키가 있고 다다음키의 '앞'키가 뭔가 있으면 패스의 일부분으로 간주 v3 = pCurrKey->GetpNextPathKey()->GetpNextPathKey()->GetPos(); else v3 = pCurrKey->GetpNextPathKey()->GetPos(); } else v3 = pCurrKey->GetPos(); } } Vec2CatmullRom( vOut, v0, v1, v2, v3, fLerp ); m_cnPos.vPos = vOut; // 스플라인위에서의 최종 좌표 } } break; } // switch // 패스의 끝까지 왔으면 패스보간모드 끝 if( fTimeLerp >= 1.0f ) m_cnPos.interpolation = xNONE; } // cnPos.interpolation // 알파보간 if( m_cnEffect.interpolation ) // 보간이동중이다 { float fFrmLength = m_cnEffect.fNextKeyFrame - m_cnEffect.fStartKeyFrame; float fSlerp = (fFrmCurr - m_cnEffect.fStartKeyFrame) / fFrmLength; if( fSlerp >= 0 ) { m_cnEffect.fAlpha = m_cnEffect.fAlphaSrc + ((m_cnEffect.fAlphaDest - m_cnEffect.fAlphaSrc) * fSlerp); if( fSlerp >= 1.0f ) m_cnEffect.interpolation = xNONE; // 묙표지점까지 왔으니 보간모드 끝 } } // 회전보간 if( m_cnRot.interpolation ) { float fFrmLength = m_cnRot.fNextKeyFrame - m_cnRot.fStartKeyFrame; float fSlerp = (fFrmCurr - m_cnRot.fStartKeyFrame) / fFrmLength; if( fSlerp >= 0 ) { m_cnRot.fAngle = m_cnRot.fAngleSrc + ((m_cnRot.fAngleDest - m_cnRot.fAngleSrc) * fSlerp); if( fSlerp >= 1.0f ) m_cnRot.interpolation = xNONE; // 묙표지점까지 왔으니 보간모드 끝 } } // 스케일 보간 if( m_cnScale.interpolation ) // 보간 { float fFrmLength = m_cnScale.fNextKeyFrame - m_cnScale.fStartKeyFrame; float fSlerp = (fFrmCurr - m_cnScale.fStartKeyFrame) / fFrmLength; if( fSlerp >= 0 ) { m_cnScale.fScaleX = m_cnScale.fScaleSrcX + ((m_cnScale.fScaleDestX - m_cnScale.fScaleSrcX) * fSlerp); m_cnScale.fScaleY = m_cnScale.fScaleSrcY + ((m_cnScale.fScaleDestY - m_cnScale.fScaleSrcY) * fSlerp); if( fSlerp >= 1.0f ) m_cnScale.interpolation = xNONE; // 묙표지점까지 왔으니 보간모드 끝 } } }