Esempio n. 1
0
  //
  // ClampToFringe
  //
  // Clamp the given cell location to the closest fringe cell
  //
  void ClampToFringe(const Point<S32> &min, const Point<S32> &max, Point<S32> &pos)
  {
    // Get fringe bounds
    Point<S32> fMin(min - 1);
    Point<S32> fMax(max + 1);

    // Clamp both values into the fringe area
    pos.x = Clamp<S32>(fMin.x, pos.x, fMax.x);
    pos.z = Clamp<S32>(fMin.z, pos.z, fMax.z);

    // For internal points, get the closest fringe for each axis
    S32 cx = (abs(fMin.x - pos.x) < abs(fMax.x - pos.x)) ? fMin.x : fMax.x;
    S32 cz = (abs(fMin.z - pos.z) < abs(fMax.z - pos.z)) ? fMin.z : fMax.z;

    // Jump to the closest fringe
    if (abs(cx - pos.x) < abs(cz - pos.z))
    {
      pos.x = cx;
    }
    else
    {
      pos.z = cz;
    }

    ASSERT(CellOnFringe(min, max, pos))
  }
Esempio n. 2
0
void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo, SamplingRateInfo *pSamplingRateInfo)
{
  int band;
  int window;
  const SHORT * RESTRICT pSfbScale  = pAacDecoderChannelInfo->pDynData->aSfbScale;
  SHORT * RESTRICT pSpecScale = pAacDecoderChannelInfo->specScale;
  int groupwin,group;
  const SHORT * RESTRICT BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
  SPECTRAL_PTR RESTRICT pSpectralCoefficient = pAacDecoderChannelInfo->pSpectralCoefficient;


  FDKmemclear(pSpecScale, 8*sizeof(SHORT));

  int max_band = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
  for (window=0, group=0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)
  {
    for (groupwin=0; groupwin < GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group); groupwin++, window++)
    {
      int SpecScale_window = pSpecScale[window];
      FIXP_DBL *pSpectrum = SPEC(pSpectralCoefficient, window,  pAacDecoderChannelInfo->granuleLength);

      /* find scaling for current window */
      for (band=0; band < max_band; band++)
      {
        SpecScale_window = fMax(SpecScale_window, (int)pSfbScale[window*16+band]);
      }

      if (pAacDecoderChannelInfo->pDynData->TnsData.Active) {
        SpecScale_window += TNS_SCALE;
      }

      /* store scaling of current window */
      pSpecScale[window] = SpecScale_window;

#ifdef FUNCTION_CBlock_ScaleSpectralData_func1

      CBlock_ScaleSpectralData_func1(pSpectrum, max_band, BandOffsets, SpecScale_window, pSfbScale, window);

#else /* FUNCTION_CBlock_ScaleSpectralData_func1 */
      for (band=0; band < max_band; band++)
      {
        int scale = SpecScale_window - pSfbScale[window*16+band];
        if (scale)
        {
          /* following relation can be used for optimizations: (BandOffsets[i]%4) == 0 for all i */
          int max_index = BandOffsets[band+1];
          for (int index = BandOffsets[band]; index < max_index; index++)
          {
            pSpectrum[index] >>= scale;
          }
        }
      }
#endif  /* FUNCTION_CBlock_ScaleSpectralData_func1 */
    }
  }

}
Esempio n. 3
0
  //
  // CellOnFringe
  //
  // Is the given map cell on the fringe of the given footprint
  //
  Bool CellOnFringe(const Point<S32> &min, const Point<S32> &max, const Point<S32> &pos)
  {
    // Get fringe bounds
    Point<S32> fMin(min - 1);
    Point<S32> fMax(max + 1);

    return 
    (
      (((pos.x == fMin.x) || (pos.x == fMax.x)) && ((pos.z >= fMin.z && pos.z <= fMax.z)))

      ||

      (((pos.z == fMin.z) || (pos.z == fMax.z)) && ((pos.x >= fMin.x && pos.x <= fMax.x)))
    );    
  }
Esempio n. 4
0
void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
                       PVC_DYNAMIC_DATA *pPvcDynamicData,
                       FIXP_DBL **qmfSlotReal, FIXP_DBL **qmfSlotImag,
                       const int qmfExponent, const int pvcBorder0,
                       const int timeSlotNumber, FIXP_DBL predictedEsgSlot[],
                       int *predictedEsg_exp) {
  int i, band, ksg, ksg_start = 0;
  int RATE = pPvcDynamicData->RATE;
  int Esg_index = pPvcStaticData->Esg_slot_index;
  const SCHAR *sg_borders = pPvcDynamicData->sg_offset_low;
  FIXP_DBL *pEsg = pPvcStaticData->Esg[Esg_index];
  FIXP_DBL E[PVC_NBLOW] = {0};

  /* Subband grouping in QMF subbands below SBR range */
  /* Within one timeslot ( i = [0...(RATE-1)] QMF subsamples) calculate energy
     E(ib,t) and group them to Esg(ksg,t). Then transfer values to logarithmical
     domain and store them for time domain smoothing. (7.5.6.3 Subband grouping
     in QMF subbands below SBR range)
  */
  for (ksg = 0; sg_borders[ksg] < 0; ksg++) {
    pEsg[ksg] = FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)); /* 10*log10(0.1) */
    ksg_start++;
  }

  for (i = 0; i < RATE; i++) {
    FIXP_DBL *qmfR, *qmfI;
    qmfR = qmfSlotReal[i];
    qmfI = qmfSlotImag[i];
    for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
      for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) {
        /* The division by 8 == (RATE*lbw) is required algorithmically */
        E[ksg] += (fPow2Div2(qmfR[band]) + fPow2Div2(qmfI[band])) >> 2;
      }
    }
  }
  for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
    if (E[ksg] > (FIXP_DBL)0) {
      /* 10/log2(10) = 0.752574989159953 * 2^2 */
      int exp_log;
      FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent, &exp_log);
      nrg = fMult(nrg, FL2FXCONST_SGL(LOG10FAC));
      nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2);
      pEsg[ksg] = fMax(nrg, FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)));
    } else {
      pEsg[ksg] =
          FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)); /* 10*log10(0.1) */
    }
  }

  /* Time domain smoothing of subband-grouped energy */
  {
    int idx = pPvcStaticData->Esg_slot_index;
    FIXP_DBL *pEsg_filt;
    FIXP_SGL SCcoeff;

    E[0] = E[1] = E[2] = (FIXP_DBL)0;
    for (i = 0; i < pPvcDynamicData->ns; i++) {
      SCcoeff = pPvcDynamicData->pSCcoeffs[i];
      pEsg_filt = pPvcStaticData->Esg[idx];
      /* Div2 is compensated by scaling of coeff table */
      E[0] = fMultAddDiv2(E[0], pEsg_filt[0], SCcoeff);
      E[1] = fMultAddDiv2(E[1], pEsg_filt[1], SCcoeff);
      E[2] = fMultAddDiv2(E[2], pEsg_filt[2], SCcoeff);
      if (i >= pPvcDynamicData->pastEsgSlotsAvail) {
        /* if past Esg values are not available use the ones from the last valid
         * slot */
        continue;
      }
      if (idx > 0) {
        idx--;
      } else {
        idx += PVC_NS_MAX - 1;
      }
    }
  }

  /* SBR envelope scalefactor prediction */
  {
    int E_high_exp[PVC_NBHIGH_MAX];
    int E_high_exp_max = 0;
    int pvcTab1ID;
    int pvcTab2ID = (int)pPvcDynamicData->pPvcID[timeSlotNumber];
    const UCHAR *pTab1, *pTab2;
    if (pvcTab2ID < pPvcDynamicData->pPVCTab1_dp[0]) {
      pvcTab1ID = 0;
    } else if (pvcTab2ID < pPvcDynamicData->pPVCTab1_dp[1]) {
      pvcTab1ID = 1;
    } else {
      pvcTab1ID = 2;
    }
    pTab1 = &(pPvcDynamicData
                  ->pPVCTab1[pvcTab1ID * PVC_NBLOW * pPvcDynamicData->nbHigh]);
    pTab2 = &(pPvcDynamicData->pPVCTab2[pvcTab2ID * pPvcDynamicData->nbHigh]);
    for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
      FIXP_SGL predCoeff;
      FIXP_DBL accu;
      int predCoeff_exp, kb;
      E_high_exp[ksg] = 0;

      /* residual part */
      accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP +
                                         pPvcDynamicData->pScalingCoef[3]);

      /* linear combination of lower grouped energies part */
      for (kb = 0; kb < PVC_NBLOW; kb++) {
        predCoeff = (FIXP_SGL)(
            (SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8);
        predCoeff_exp = pPvcDynamicData->pScalingCoef[kb] +
                        1; /* +1 to compensate for Div2 */
        accu += fMultDiv2(E[kb], predCoeff) << predCoeff_exp;
      }
      /* convert back to linear domain */
      accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV));
      accu = f2Pow(
          accu, PVC_ESG_EXP - 1,
          &predCoeff_exp); /* -1 compensates for exponent of LOG10FAC_INV */
      predictedEsgSlot[ksg] = accu;
      E_high_exp[ksg] = predCoeff_exp;
      if (predCoeff_exp > E_high_exp_max) {
        E_high_exp_max = predCoeff_exp;
      }
    }

    /* rescale output vector according to largest exponent */
    for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
      int scale = E_high_exp[ksg] - E_high_exp_max;
      predictedEsgSlot[ksg] = scaleValue(predictedEsgSlot[ksg], scale);
    }
    *predictedEsg_exp = E_high_exp_max;
  }

  pPvcStaticData->Esg_slot_index =
      (pPvcStaticData->Esg_slot_index + 1) & (PVC_NS_MAX - 1);
  pPvcDynamicData->pastEsgSlotsAvail =
      fMin(pPvcDynamicData->pastEsgSlotsAvail + 1, PVC_NS_MAX - 1);
  return;
}
Esempio n. 5
0
/*!
  \brief Decode channel pair element

  The function decodes a channel pair element.

  \return  none
*/
void CChannelElement_Decode(
    CAacDecoderChannelInfo
        *pAacDecoderChannelInfo[2], /*!< pointer to aac decoder channel info */
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
    SamplingRateInfo *pSamplingRateInfo, UINT flags, UINT elFlags,
    int el_channels) {
  int ch = 0;

  int maxSfBandsL = 0, maxSfBandsR = 0;
  int maybe_jstereo = (el_channels > 1);

  if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && el_channels == 2) {
    if (pAacDecoderChannelInfo[L]->data.usac.core_mode ||
        pAacDecoderChannelInfo[R]->data.usac.core_mode) {
      maybe_jstereo = 0;
    }
  }

  if (maybe_jstereo) {
    maxSfBandsL =
        GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[L]->icsInfo);
    maxSfBandsR =
        GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[R]->icsInfo);

    /* apply ms */
    if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
      if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
        if (pAacDecoderChannelInfo[L]->data.aac.PnsData.PnsActive ||
            pAacDecoderChannelInfo[R]->data.aac.PnsData.PnsActive) {
          MapMidSideMaskToPnsCorrelation(pAacDecoderChannelInfo);
        }
      }
      /* if tns_on_lr == 1 run MS */ /* &&
                                        (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_active
                                        == 1) */
      if (((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
           (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
            1)) ||
          ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) == 0)) {
        int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);

        CJointStereo_ApplyMS(
            pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
            pAacDecoderChannelInfo[L]->pSpectralCoefficient,
            pAacDecoderChannelInfo[R]->pSpectralCoefficient,
            pAacDecoderChannelInfo[L]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[R]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[L]->specScale,
            pAacDecoderChannelInfo[R]->specScale,
            GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
                                      pSamplingRateInfo),
            GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
            GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), max_sfb_ste,
            maxSfBandsL, maxSfBandsR,
            pAacDecoderChannelInfo[L]
                ->pComData->jointStereoData.store_dmx_re_prev,
            &(pAacDecoderChannelInfo[L]
                  ->pComData->jointStereoData.store_dmx_re_prev_e),
            1);

      } /* if ( ((elFlags & AC_EL_USAC_CP_POSSIBLE).... */
    }   /* if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow)*/

    /* apply intensity stereo */ /* modifies pAacDecoderChannelInfo[]->aSpecSfb
                                  */
    if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
      if ((pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ==
           1) &&
          (el_channels == 2)) {
        CJointStereo_ApplyIS(
            pAacDecoderChannelInfo,
            GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
                                      pSamplingRateInfo),
            GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
            GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo),
            GetScaleFactorBandsTransmitted(
                &pAacDecoderChannelInfo[L]->icsInfo));
      }
    }
  } /* maybe_stereo */

  for (ch = 0; ch < el_channels; ch++) {
    if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_LPD) {
      /* Decode LPD data */
      CLpdChannelStream_Decode(pAacDecoderChannelInfo[ch],
                               pAacDecoderStaticChannelInfo[ch], flags);
    } else {
      UCHAR noSfbs =
          GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[ch]->icsInfo);
      /* For USAC common window: max_sfb of both channels may differ
       * (common_max_sfb == 0). */
      if ((maybe_jstereo == 1) &&
          (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ==
           1)) {
        noSfbs = fMax(maxSfBandsL, maxSfBandsR);
      }
      int CP_active = 0;
      if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
        CP_active = pAacDecoderChannelInfo[ch]
                        ->pComData->jointStereoData.cplx_pred_flag;
      }

      /* Omit writing of pAacDecoderChannelInfo[ch]->specScale for complex
         stereo prediction since scaling has already been carried out. */
      int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);

      if ((!CP_active) || (CP_active && (max_sfb_ste < noSfbs)) ||
          ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
           (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
            0))) {
        CBlock_ScaleSpectralData(pAacDecoderChannelInfo[ch], noSfbs,
                                 pSamplingRateInfo);

        /*Active for the case of TNS applied before MS/CP*/
        if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
            (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
             0)) {
          if (IsLongBlock(&pAacDecoderChannelInfo[ch]->icsInfo)) {
            for (int i = 0; i < noSfbs; i++) {
              pAacDecoderChannelInfo[ch]->pDynData->aSfbScale[i] =
                  pAacDecoderChannelInfo[ch]->specScale[0];
            }
          } else {
            for (int i = 0; i < 8; i++) {
              for (int j = 0; j < noSfbs; j++) {
                pAacDecoderChannelInfo[ch]->pDynData->aSfbScale[i * 16 + j] =
                    pAacDecoderChannelInfo[ch]->specScale[i];
              }
            }
          }
        }
      }
    }
  } /* End "for (ch = 0; ch < el_channels; ch++)" */

  if (maybe_jstereo) {
    /* apply ms */
    if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
    } /* CommonWindow */
    else {
      if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
        FDKmemclear(
            pAacDecoderStaticChannelInfo[L]
                ->pCpeStaticData->jointStereoPersistentData.alpha_q_re_prev,
            JointStereoMaximumGroups * JointStereoMaximumBands * sizeof(SHORT));
        FDKmemclear(
            pAacDecoderStaticChannelInfo[L]
                ->pCpeStaticData->jointStereoPersistentData.alpha_q_im_prev,
            JointStereoMaximumGroups * JointStereoMaximumBands * sizeof(SHORT));
      }
    }

  } /* if (maybe_jstereo) */

  for (ch = 0; ch < el_channels; ch++) {
    if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_LPD) {
    } else {
      if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
        /* Use same seed for coupled channels (CPE) */
        int pnsCh = (ch > 0) ? L : ch;
        CPns_UpdateNoiseState(
            &pAacDecoderChannelInfo[ch]->data.aac.PnsData,
            pAacDecoderChannelInfo[pnsCh]->data.aac.PnsData.currentSeed,
            pAacDecoderChannelInfo[ch]->pComData->pnsRandomSeed);
      }

      if ((!(flags & (AC_USAC))) ||
          ((flags & (AC_USAC)) &&
           (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_active ==
            1)) ||
          (maybe_jstereo == 0)) {
        ApplyTools(
            pAacDecoderChannelInfo, pSamplingRateInfo, flags, elFlags, ch,
            pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow);
      }
    } /* End "} else" */
  }   /* End "for (ch = 0; ch < el_channels; ch++)" */

  if (maybe_jstereo) {
    /* apply ms */
    if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
      /* if tns_on_lr == 0 run MS */
      if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
          (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
           0)) {
        int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);

        CJointStereo_ApplyMS(
            pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
            pAacDecoderChannelInfo[L]->pSpectralCoefficient,
            pAacDecoderChannelInfo[R]->pSpectralCoefficient,
            pAacDecoderChannelInfo[L]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[R]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[L]->specScale,
            pAacDecoderChannelInfo[R]->specScale,
            GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
                                      pSamplingRateInfo),
            GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
            GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), max_sfb_ste,
            maxSfBandsL, maxSfBandsR,
            pAacDecoderChannelInfo[L]
                ->pComData->jointStereoData.store_dmx_re_prev,
            &(pAacDecoderChannelInfo[L]
                  ->pComData->jointStereoData.store_dmx_re_prev_e),
            1);
      }

    } /* if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) */

  } /* if (maybe_jstereo) */

  for (ch = 0; ch < el_channels; ch++) {
    if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
      pAacDecoderStaticChannelInfo[L]
          ->pCpeStaticData->jointStereoPersistentData.clearSpectralCoeffs = 0;
    }
  }

  CRvlc_ElementCheck(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
                     flags, el_channels);
}
Esempio n. 6
0
// Load a mesh using the assimp library, and calculate its mesh saliency
bool load_mesh (const char* file_name, GLuint* vao, int* point_count) {
	const aiScene* scene = aiImportFile (file_name, aiProcess_Triangulate);
	if (!scene) {
		fprintf (stderr, "ERROR: reading mesh %s\n", file_name);
		return false;
	}
   
	// Get first mesh in file only
	const aiMesh* mesh = scene->mMeshes[0];
	printf ("    %i vertices in mesh[0]\n", mesh->mNumVertices);
	printf ("    %i faces in mesh[0]\n", mesh->mNumFaces);
	
	// Pass back number of vertex points in mesh 
	*point_count = mesh->mNumVertices;
    vertexCnt = *point_count;
	
	// Generate a VAO, using the pass-by-reference parameter that we give to the function 
    glGenVertexArrays (1, vao);
	glBindVertexArray (*vao);
	
	points = NULL; // array of vertex points
    if (!mesh->HasPositions()) {
        fprintf(stderr, "ERROR: mesh %s don't have vertex data!\n", file_name);
        return false;
    }

    float xMin = oo, yMin = oo, zMin = oo;
    float xMax = -oo, yMax = -oo, zMax = -oo;
    // Get the mesh's vertecies
    points = (GLfloat*)malloc (vertexCnt * 3 * sizeof (GLfloat));
    for (int i = 0; i < vertexCnt; i++) {
        const aiVector3D* vp = &(mesh->mVertices[i]);
        points[i * 3] = (GLfloat)vp->x;
        points[i * 3 + 1] = (GLfloat)vp->y;
        points[i * 3 + 2] = (GLfloat)vp->z;
        xMin = fMin(xMin, vp->x), xMax = fMax(xMax, vp->x);
        yMin = fMin(yMin, vp->y), yMax = fMax(yMax, vp->y);
        zMin = fMin(zMin, vp->z), zMax = fMax(zMax, vp->z);
    }

    // Calculate the mesh's normal
    normals = (GLfloat*)malloc(vertexCnt * 3 * sizeof(GLfloat));
    for(int i = 0; i < mesh->mNumFaces; i++) {
        int idx[3];
        for(int k = 0; k < 3; k++)
            idx[k] = mesh->mFaces[i].mIndices[k];
        // get all vertecies' location
        const aiVector3D* v1 = &(mesh->mVertices[idx[0]]);
        const aiVector3D* v2 = &(mesh->mVertices[idx[1]]);
        const aiVector3D* v3 = &(mesh->mVertices[idx[2]]);
        // vectors
        vec3 faceVec1 = vec3(v2->x - v1->x, v2->y - v1->y, v2->z - v1->z);
        vec3 faceVec2 = vec3(v3->x - v2->x, v3->y - v2->y, v3->z - v2->z);
        vec3 crossProd = cross(faceVec1, faceVec2);
        for(int k = 0; k < 3; k++) {
            normals[idx[k]*3+0] += (GLfloat)crossProd.v[0],
            normals[idx[k]*3+1] += (GLfloat)crossProd.v[1],
            normals[idx[k]*3+2] += (GLfloat)crossProd.v[2];
         }
    }

    for(int i = 0; i < vertexCnt; i++) {
        float norm = 0.0f;
        for(int k = 0; k < 3; k++)
            norm += normals[i*3+k]*normals[i*3+k];
        for(int k = 0; k < 3; k++)
            normals[i*3+k] /= sqrt(norm);
    }

    // Calculate each vertecies' shape operator
    mat3* shapeOperators = NULL;
    float* vertexArea = NULL;
    shapeOperators = (mat3*)malloc(vertexCnt * sizeof(mat3));
    vertexArea = (float*)malloc(vertexCnt * sizeof(float));
    for(int i = 0; i < vertexCnt ; i++) {
        vertexArea[i] = 0.0f;
        for(int j = 0; j < 9; j++)
            shapeOperators[i].m[j] = 0.0f;
    }
    for(int k = 0; k < mesh->mNumFaces; k++) {
        // Calculate the face's area
        aiVector3D* aiVec[3];
        for(int idx = 0; idx < 3; idx++)
            aiVec[idx] = &(mesh->mVertices[mesh->mFaces[k].mIndices[idx]]);
        vec3 faceVec1 = vec3(aiVec[1]->x - aiVec[0]->x, 
                             aiVec[1]->y - aiVec[0]->y, 
                             aiVec[1]->z - aiVec[0]->z);
        vec3 faceVec2 = vec3(aiVec[2]->x - aiVec[1]->x,
                             aiVec[2]->y - aiVec[1]->y,
                             aiVec[2]->z - aiVec[1]->z);
        vec3 vecArea = cross(faceVec1, faceVec2);
        float faceArea = sqrt(vecArea.v[0]*vecArea.v[0] + vecArea.v[1]*vecArea.v[1] + vecArea.v[2]*vecArea.v[2]);

        for(int idx = 0; idx < 3; idx++) {
            int i = mesh->mFaces[k].mIndices[idx];
            int j = mesh->mFaces[k].mIndices[(idx+1)%3];
            // Get vertex i and j's normal vectors.
            vec3 Ni = vec3(normals[i*3], normals[i*3+1], normals[i*3+2]);
            vec3 Nj = vec3(normals[j*3], normals[j*3+1], normals[j*3+2]);
            // Get vertex i and j's location.
            const aiVector3D* aiVi = &(mesh->mVertices[i]);
            const aiVector3D* aiVj = &(mesh->mVertices[j]);
            vec3 Vi = vec3(aiVi->x, aiVi->y, aiVi->z);
            vec3 Vj = vec3(aiVj->x, aiVj->y, aiVj->z);
            
            // For vertex i, update the relative part of its shape operator
            vec3 Tij = (identity_mat3() - wedge(Ni, Ni))*(Vi-Vj);
            Tij = normalise(Tij);
            float kappa_ij = 2*dot(Ni, Vj-Vi);
            kappa_ij /= get_squared_dist(Vi, Vj);
            // Maintain vi's shape operator
            shapeOperators[i] = shapeOperators[i] + (wedge(Tij, Tij) * (kappa_ij * faceArea));
            vertexArea[i] += faceArea;

            // For vertex j, update the relative part of its shape operator
            vec3 Tji = (identity_mat3() - wedge(Nj, Nj))*(Vj-Vi);
            Tji = normalise(Tji);
            float kappa_ji = 2*dot(Nj, Vi-Vj);
            kappa_ji /= get_squared_dist(Vi, Vj);
            // Maintain vj's shape operator
            shapeOperators[j] = shapeOperators[j] + (wedge(Tji, Tji) * (kappa_ji * faceArea));
            
            vertexArea[j] += faceArea;
        }
    }

    for(int i = 0; i < vertexCnt; i++) {
        shapeOperators[i] = shapeOperators[i] * (1.0f/vertexArea[i]);// * 10000000.0f;
        //print(shapeOperators[i]);
    }
    free(vertexArea);

    // Diagonalize the shape operator, and get the mean curvature
    meanCurvature = (float*)malloc(vertexCnt * sizeof(float));
    for(int k = 0; k < vertexCnt; k++) {
        vec3 E1 = vec3(1.0f, 0.0f, 0.0f);
        vec3 Nk = vec3(normals[k*3], normals[k*3+1], normals[k*3+2]);
        bool isMinus = get_squared_dist(E1, Nk) > get_squared_dist(E1 * (-1.0f), Nk);
        vec3 Wk;
        // Diagnoalization by the Householder transform
        if (!isMinus)
            Wk = E1 + Nk;
        else
            Wk = E1 - Nk;
        Wk = normalise(Wk);
        mat3 Qk = identity_mat3() - (wedge(Wk, Wk) * 2.0f);
        mat3 Mk = transpose(Qk) * shapeOperators[k] * Qk;
        // Calculate the mean curvature by M_k's trace;
        meanCurvature[k] = (GLfloat)(Mk.m[4] + Mk.m[8]);
    }
    free(shapeOperators);

    // Calculate the incident matrix ( as linked list )
    int* first = NULL;
    int* next = NULL;
    int* incidentVertex = NULL;
    first = (int*)malloc(vertexCnt * sizeof(int));
    for(int i = 0; i < vertexCnt; i++)
        first[i] = -1;
    next = (int*)malloc(mesh->mNumFaces * 6 * sizeof(int));
    incidentVertex = (int*)malloc(mesh->mNumFaces * 6 * sizeof(int));
    int edgeCnt = 0;
    for(int k = 0; k < mesh->mNumFaces; k++) {
        int idx[3];
        for(int i = 0; i < 3; i++)
            idx[i] = mesh->mFaces[k].mIndices[i];
        for(int i = 0; i < 3; i++) {
            int j1 = idx[(i+1)%3], j2 = idx[(i+2)%3];
            incidentVertex[++edgeCnt] = j1;
            next[edgeCnt] = first[idx[i]]; first[idx[i]] = edgeCnt;
            incidentVertex[++edgeCnt] = j2;
            next[edgeCnt] = first[idx[i]]; first[idx[i]] = edgeCnt;
        }
    }
    
    printf("BFS 1\n");
    // Calculate the mesh saliency by BFS
    float diagonalLength = sqrt((xMax-xMin)*(xMax-xMin) + (yMax-yMin)*(yMax-yMin) + (zMax-zMin)*(zMax-zMin));
    float sigma = 0.003 * diagonalLength;
    float* saliency[7];
    float maxSaliency[7];
    for(int i = 2; i <= 6; i++) {
        saliency[i] = NULL;;
        saliency[i] = (float*)malloc(vertexCnt * sizeof(float));
        maxSaliency[i] = -oo;
    }

    // Labeled the vertecies whether covered or not.
    bool* used = NULL;
    used = (bool*)malloc(vertexCnt * sizeof(bool));
    for(int k = 0; k < vertexCnt; k++) {
        if(k%1000 == 0)
            printf("#%d#\n", k);
        // Initialize the saliency and its local counter.
        for(int i = 2; i <= 6; i++)
            saliency[i][k] = 0.0f;
        // Initialize the saliency's Gaussian filter.
        float gaussianSigma1[7], gaussianSigma2[7], sumSigma1[7], sumSigma2[7];
        for(int i = 2; i <= 6; i++)
            gaussianSigma1[i] = gaussianSigma2[i] = 0.0f,
            sumSigma1[i] = sumSigma2[i] = 0.0f;
        // Get the current vertex's information.
        aiVector3D* aiVec = &(mesh->mVertices[k]);
        vec3 vVec = vec3(aiVec->x, aiVec->y, aiVec->z);
        // Initialize the queue to find neighbourhood.
        for(int i = 0; i < vertexCnt; i++)
            used[i] = false;
        queue<int> Q;
        Q.push(k);
        used[k] = true;
        // Frsit BFS
        while(!Q.empty()) {
            // Get the front element in the queue.
            int idx = Q.front(); Q.pop();
            aiVec = &(mesh->mVertices[idx]);
            vec3 idxVec = vec3(aiVec->x, aiVec->y, aiVec->z);
            // Put the next level vertecies into the queue.
            for(int e = first[idx]; e != -1; e = next[e]) {
                int idxNext = incidentVertex[e];
                // Expand the next level vertecies.
                if(!used[idxNext]) {
                    aiVec = &(mesh->mVertices[idxNext]);
                    vec3 idxNextVec = vec3(aiVec->x, aiVec->y, aiVec->z);
                    if(get_squared_dist(vVec, idxNextVec) <= 36*sigma*sigma)
                        Q.push(incidentVertex[e]),
                        used[incidentVertex[e]] = 1;
                }
            }
            // Update Gaussian filter
            float dist = get_squared_dist(vVec, idxVec);
            for(int i = 2; i <= 6; i++) {
                float sigmaHere = i*i*sigma*sigma;
                if(dist <= sigmaHere) {
                    float factor = exp(-dist/(2*sigmaHere));
                    gaussianSigma1[i] += meanCurvature[idx] * factor;
                    sumSigma1[i] += factor;
                }
                if(dist <= 2*sigmaHere) {
                    float factor = exp(-dist/(8*sigma*sigma));
                    gaussianSigma2[i] += meanCurvature[idx] * factor;
                    sumSigma2[i] += factor;
                }
            }
        }
        for(int i = 2; i <= 6; i++) {
            saliency[i][k] = fabs(gaussianSigma1[i]/sumSigma1[i]
                                - gaussianSigma2[i]/sumSigma2[i]);
            maxSaliency[i] = fMax(maxSaliency[i], saliency[i][k]);
        }
    }

    printf("BFS 2\n");
    // Second BFS and get the non-linear normailization of suppressian's saliency.
    smoothSaliency = (float*)malloc(vertexCnt * sizeof(float));
    for(int k = 0; k < vertexCnt; k++) {
        if(k%1000 == 0)
            printf("[%d]\n", k);
        smoothSaliency[k] = 0.0f;
        float localMaxSaliency[7];//, localCntSaliency[7];
        for(int i = 2; i <= 6; i++)
            localMaxSaliency[i] = -oo;
        // Get the current vertex's information.
        aiVector3D* aiVec = &(mesh->mVertices[k]);
        vec3 vVec = vec3(aiVec->x, aiVec->y, aiVec->z);
        // Initialize the queue to find neighbourhood.
        for(int i = 0; i < vertexCnt; i++)
            used[i] = false;
        queue<int> Q;
        Q.push(k);
        used[k] = true;
        while(!Q.empty()) {
            // Get the front element in the queue.
            int idx = Q.front(); Q.pop();
            //aiVec = &(mesh->mVertices[idx]);
            //vec3 idxVec = vec3(aiVec->x, aiVec->y, aiVec->z);
            // Put the next level vertecies into the queue.
            for(int e = first[idx]; e != -1; e = next[e]) {
                int idxNext = incidentVertex[e]; 
                // Expand the next level vertecies.
                if(!used[idxNext]) {
                    aiVec = &(mesh->mVertices[idxNext]); 
                    vec3 idxNextVec = vec3(aiVec->x, aiVec->y, aiVec->z);
                    if(get_squared_dist(vVec, idxNextVec) <= 36*sigma*sigma)
                        Q.push(incidentVertex[ e]),
                        used[incidentVertex[e]] = 1;
                }
            }
            // Update Gaussian filter
            for(int i = 2; i <= 6; i++) 
                localMaxSaliency[i] = fMax(localMaxSaliency[i], saliency[i][idx]);
        }
        // Calculate the weighted saliency
        float saliencySum = 0.0f;
        for(int i = 2; i <= 6; i++) {
            float factor = (maxSaliency[i]-localMaxSaliency[i])*(maxSaliency[i]-localMaxSaliency[i]);
            smoothSaliency[k] += (GLfloat)saliency[i][k] * factor;
            saliencySum += factor;
        }
        smoothSaliency[k] /= (GLfloat)saliencySum;
    }

    // Clean up resources
    free(first);
    free(next);
    free(incidentVertex);
    for(int i = 2; i <= 6; i++)
        free(saliency[i]);
    
	// Copy all vertecies and normal vertors in mesh data into VBOs
    /*
    {
        GLuint vbo;
        glGenBuffers (1, &vbo);
        glBindBuffer (GL_ARRAY_BUFFER, vbo);
        glBufferData (
            GL_ARRAY_BUFFER,
            3 * vertexCnt * sizeof (GLfloat),
            points,
            GL_STATIC_DRAW
        );
        glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
        glEnableVertexAttribArray (0);
        free (points);
    }
    */

    // Copy all normal vectors in mesh data into VBOs
    updateDisplayType(1);
	aiReleaseImport (scene);
	printf ("mesh loaded\n");
	
	return true;
}
Esempio n. 7
0
void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
                           const int start_band, const int stop_band,
                           FIXP_DBL *pQmfOutReal, FIXP_DBL *pQmfOutImag,
                           const int exp_out) {
  FDK_ASSERT(qd_ch != NULL);
  FDK_ASSERT(pQmfOutReal != NULL);
  HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
  const FIXP_DBL *real = qd_ch->hQmfSlotsReal[ts];
  const FIXP_DBL *imag = qd_ch->hQmfSlotsImag[ts];
  const int ovSlots = gc->nQmfOvTimeSlots;
  const int exp_lb = SCALE2EXP((ts < ovSlots) ? qd_ch->scaling.ov_lb_scale
                                              : qd_ch->scaling.lb_scale);
  const int exp_hb = SCALE2EXP(qd_ch->scaling.hb_scale);
  const int lsb = qd_ch->fb.lsb;
  const int usb = qd_ch->fb.usb;
  int b = start_band;
  int lb_sf, hb_sf;

  int target_exp =
      ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + qd_ch->fb.filterScale;

  FDK_ASSERT(ts < (gc->nQmfTimeSlots + gc->nQmfOvTimeSlots));
  FDK_ASSERT(start_band >= 0);
  FDK_ASSERT(stop_band <= gc->nQmfProcBands);

  if (qd_ch->fb.no_channels == 24) {
    target_exp -= 1;
  }

  /* Limit scaling factors to maximum negative value to avoid faulty behaviour
     due to right-shifts. Corresponding asserts were observed during robustness
     testing.
   */
  lb_sf = fMax(exp_lb - target_exp - exp_out, -31);
  FDK_ASSERT(lb_sf < 32);
  hb_sf = fMax(exp_hb - target_exp - exp_out, -31);
  FDK_ASSERT(hb_sf < 32);

  if (pQmfOutImag == NULL) {
    for (; b < fMin(lsb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], lb_sf);
    }
    for (; b < fMin(usb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], hb_sf);
    }
    for (; b < stop_band; b++) {
      pQmfOutReal[b] = (FIXP_DBL)0;
    }
  } else {
    FDK_ASSERT(imag != NULL);
    for (; b < fMin(lsb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], lb_sf);
      pQmfOutImag[b] = scaleValue(imag[b], lb_sf);
    }
    for (; b < fMin(usb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], hb_sf);
      pQmfOutImag[b] = scaleValue(imag[b], hb_sf);
    }
    for (; b < stop_band; b++) {
      pQmfOutReal[b] = (FIXP_DBL)0;
      pQmfOutImag[b] = (FIXP_DBL)0;
    }
  }
}
Esempio n. 8
0
int FDK_QmfDomain_InitFilterBank(HANDLE_FDK_QMF_DOMAIN qd, UINT extra_flags) {
  FDK_ASSERT(qd != NULL);
  int err = 0;
  int ch, ts;
  HANDLE_FDK_QMF_DOMAIN_GC gc = &qd->globalConf;
  int noCols = gc->nQmfTimeSlots;
  int lsb = gc->nBandsAnalysis;
  int usb = fMin((INT)gc->nBandsSynthesis, 64);
  int nProcBands = gc->nQmfProcBands;
  FDK_ASSERT(nProcBands % ALIGNMENT_DEFAULT == 0);

  if (extra_flags & QMF_FLAG_MPSLDFB) {
    gc->flags &= ~QMF_FLAG_CLDFB;
    gc->flags |= QMF_FLAG_MPSLDFB;
  }
  for (ch = 0; ch < gc->nInputChannels; ch++) {
    /* distribute memory to slots array */
    FIXP_DBL *ptrOv =
        qd->QmfDomainIn[ch].pOverlapBuffer; /* persistent memory for overlap */
    if ((ptrOv == NULL) && (gc->nQmfOvTimeSlots != 0)) {
      err = 1;
      return err;
    }
    /* This assumes the workbuffer defined for ch0 is the big one being used to
     * hold one full frame of QMF data. */
    FIXP_DBL **ptr =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .pWorkBuffer; /* non-persistent workbuffer */
    USHORT workBufferOffset =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .workBufferOffset;
    USHORT workBufferSectSize =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .workBufferSectSize;

    if ((ptr == NULL) && (gc->nQmfTimeSlots != 0)) {
      err = 1;
      return err;
    }

    qd->QmfDomainIn[ch].pGlobalConf = gc;
    for (ts = 0; ts < gc->nQmfOvTimeSlots; ts++) {
      qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = ptrOv;
      ptrOv += nProcBands;
      qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = ptrOv;
      ptrOv += nProcBands;
    }
    for (; ts < (gc->nQmfOvTimeSlots + gc->nQmfTimeSlots); ts++) {
      qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = FDK_getWorkBuffer(
          ptr, workBufferOffset, workBufferSectSize, nProcBands);
      workBufferOffset += nProcBands;
      qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = FDK_getWorkBuffer(
          ptr, workBufferOffset, workBufferSectSize, nProcBands);
      workBufferOffset += nProcBands;
    }
    err |= qmfInitAnalysisFilterBank(
        &qd->QmfDomainIn[ch].fb, qd->QmfDomainIn[ch].pAnaQmfStates, noCols,
        (qd->QmfDomainIn[ch].fb.lsb == 0) ? lsb : qd->QmfDomainIn[ch].fb.lsb,
        (qd->QmfDomainIn[ch].fb.usb == 0) ? usb : qd->QmfDomainIn[ch].fb.usb,
        gc->nBandsAnalysis, gc->flags | extra_flags);
  }

  for (ch = 0; ch < gc->nOutputChannels; ch++) {
    FIXP_DBL outGain_m = qd->QmfDomainOut[ch].fb.outGain_m;
    int outGain_e = qd->QmfDomainOut[ch].fb.outGain_e;
    int outScale = qmfGetOutScalefactor(&qd->QmfDomainOut[ch].fb);
    err |= qmfInitSynthesisFilterBank(
        &qd->QmfDomainOut[ch].fb, qd->QmfDomainOut[ch].pSynQmfStates, noCols,
        (qd->QmfDomainOut[ch].fb.lsb == 0) ? lsb : qd->QmfDomainOut[ch].fb.lsb,
        (qd->QmfDomainOut[ch].fb.usb == 0) ? usb : qd->QmfDomainOut[ch].fb.usb,
        gc->nBandsSynthesis, gc->flags | extra_flags);
    if (outGain_m != (FIXP_DBL)0) {
      qmfChangeOutGain(&qd->QmfDomainOut[ch].fb, outGain_m, outGain_e);
    }
    if (outScale) {
      qmfChangeOutScalefactor(&qd->QmfDomainOut[ch].fb, outScale);
    }
  }

  return err;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    double *points,a,b,b2,f,e2,eps2,ec;
    size_t numVec,i;
    mxArray *retMat;
    double *retData;
    
    if(nrhs>3||nrhs<1){
        mexErrMsgTxt("Wrong number of inputs");
    }
    
    if(nlhs>1) {
        mexErrMsgTxt("Wrong number of outputs.");
        return;
    }
    
    checkRealDoubleArray(prhs[0]);
    numVec = mxGetN(prhs[0]);
    
    if(mxGetM(prhs[0])!=3) {
        mexErrMsgTxt("The input vector has a bad dimensionality.");
    }
    
    points=(double*)mxGetData(prhs[0]);
    //points[0] is x
    //points[1] is y
    //points[2] is z
    
    if(nrhs>1) {
        a=getDoubleFromMatlab(prhs[1]);
    } else {
        a=getScalarMatlabClassConst("Constants", "WGS84SemiMajorAxis");
    }

    if(nrhs>2) {
        f=getDoubleFromMatlab(prhs[2]);
    } else {
        f=getScalarMatlabClassConst("Constants", "WGS84Flattening");   
    }
    
    b=a*(1-f);//The semi-minor axis of the reference ellipsoid.
    b2=b*b;

    //The square of the first numerical eccentricity. 
    e2=2*f-f*f;
    //The square of the second numerical eccentricity.
    eps2=a*a/(b2)-1;

    //This value is used if Fukushima's method is chosen.
    ec=sqrt(1-e2);

    //Allocate space for the return variables.
    retMat=mxCreateDoubleMatrix(3,numVec,mxREAL);
    retData=(double*)mxGetData(retMat);
    
    for(i=0;i<numVec;i++) {
        double *phi, *lambda, *h;
        double x0,y0,z0;
        double r0,p,s,q;
        
        //Get the Cartesian point to convert.
        x0=points[3*i];
        y0=points[3*i+1];
        z0=points[3*i+2];
        
        //Get the addresses of where the converted components will go
        phi=retData+3*i;
        lambda=retData+3*i+1;
        h=retData+3*i+2;
        
        r0=sqrt(x0*x0+y0*y0);
        p=fabs(z0)/eps2;
        s=r0*r0/(e2*eps2);
        q=p*p-b2+s;
    
        *lambda=atan2(y0,x0);
        if(q>=0) {//Use Sofair's algorithm
            double u,v,P,Q,t,c,w,z,Ne,val;
            
            u=p/sqrt(q);
            v=b2*u*u/q;
            P=27.0*v*s/q;
            Q=pow(sqrt(P+1.0)+sqrt(P),2.0/3.0);
            t=(1.0+Q+1/Q)/6.0;
            c=u*u-1+2*t;
            //This condition prevents finite precision problems due to
            //subtraction within the square root.
            c=fMax(c,0);
            c=sqrt(c);
            w=(c-u)/2.0;

        //The z coordinate of the closest point projected on the ellipsoid.
        //The fmax command deals with precision problems when the argument
        //is nearly zero. The problems arise due to the subtraction within
        //the square root.
            z=sqrt(t*t+v)-u*w-t/2.0-1.0/4.0;
            z=fMax(z,0);
            z=copySign(sqrt(q)*(w+sqrt(z)),z0);
            
            Ne=a*sqrt(1+eps2*z*z/b2);

            //The min and max terms deals with finite precision problems.
            val=fMin(z*(eps2+1)/Ne,1);
            val=fMax(val,-1.0);
            *phi=asin(val);
            *h=r0*cos(*phi)+z0*sin(*phi)-a*a/Ne;
        } else {//Use Fukushima's algorithm.
            double Cc,P,Z,S,C;
            //A gets a value within the loop. This initialization is just
            //to silence a warning when compiling with
            //-Wconditional-uninitialized
            double A=0;
            size_t curIter;
            const size_t maxIter=6;
            
            P=r0/a;
            Z=(ec/a)*fabs(z0);

            S=Z;
            C=ec*P;

            //Loop until convergence. Assume convergence in 6 iterations.
            for(curIter=0;curIter<maxIter;curIter++) {
                double B,F,D,SNew,CNew;
                
                A=sqrt(S*S+C*C);
                B=1.5*e2*S*C*C*((P*S-Z*C)*A-e2*S*C);
                F=P*A*A*A-e2*C*C*C;
                D=Z*A*A*A+e2*S*S*S;

                SNew=D*F-B*S;
                CNew=F*F-B*C;

                SNew=SNew/CNew;
                
                if(!isFinite(SNew)) {
                    S=SNew;
                    C=1;
                    A=sqrt(S*S+C*C);
                    break;
                } else {
                    S=SNew;
                    C=1;
                }
            }
            Cc=ec*C;

            //If the point is along the z-axis, then SNew and CNew will
            //both be zero, leading to a non-finite result.
            if(!isFinite(S)) {
                *phi=copySign(pi/2,z0);
                *h=fabs(z0)-b;
            } else {
                *phi=copySign(atan(S/Cc),z0);
                *h=(r0*Cc+fabs(z0)*S-b*A)/sqrt(Cc*Cc+S*S);
            }
        }
    }

    plhs[0]=retMat;
}
Esempio n. 10
0
// Update display mode depends on keyboard state
void updateDisplayType(int type) {
    if(type != 1 && type != 2 && type != 3 && type != 4 && type != 5) {
        fprintf(stderr, "Wrong Display Type!\n");
        return;
    }

    int vertexCntHere = (type >= 4 ? simplifiedVertexCnt : vertexCnt);
    // Copy all vertecies in mesh data into VBOs
    {
        GLuint vbo;
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData (
            GL_ARRAY_BUFFER,
            3 * vertexCntHere * sizeof (GLfloat),
            type >= 4 ? simplifiedPoints : points,
            GL_STATIC_DRAW
        );
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
        glEnableVertexAttribArray(0);
    }
    // Copy all vertices' color values in mesh data into VBOs
    {
        GLuint vbo;
        glGenBuffers (1, &vbo);
        glBindBuffer (GL_ARRAY_BUFFER, vbo);
        float* colors = NULL;
        colors = (float*)malloc(vertexCntHere * 3 * sizeof(float));
        switch(type) {
            // Normals mode
            case 1: {
                        for(int i = 0; i < vertexCntHere; i++)
                            colors[3*i+0] = normals[3*i+0],
                            colors[3*i+1] = normals[3*i+1],
                            colors[3*i+2] = normals[3*i+2];
                        break;
                    }
            // Mean curvature mode
            case 2: {
                        float xMin = oo, xMax = -oo;
                        for(int i = 0; i < vertexCntHere; i++)
                            xMin = fMin(xMin, fabs(meanCurvature[i])),
                            xMax = fMax(xMax, fabs(meanCurvature[i]));
                        // Normalize the Y value
                        for(int i = 0; i < vertexCntHere; i++) {
                            float Y = 255.0f*((log(1e-8+fabs(meanCurvature[i]))-log(1e-8+xMin))
                                    / (log(1e-8+xMax)-log(1e-8+xMin)));
                            getYUVtoRGB(meanCurvature[i]>0.0, Y, 255.0f, 255.0f, colors[3*i], colors[3*i+1], colors[3*i+2]);
                        }
                        break;
                    }
            // Mesh saliency mode
            case 3: {
                         float xMin = oo, xMax = -oo;
                        for(int i = 0; i < vertexCntHere; i++)
                            xMin = fMin(xMin, fabs(smoothSaliency[i])),
                            xMax = fMax(xMax, fabs(smoothSaliency[i]));
                        // Normalize the Y value
                        for(int i = 0; i < vertexCntHere; i++) {
                            float Y = 255.0f*(log(1e-8+smoothSaliency[i])-log(1e-8+xMin))
                                    / (log(1e-8+xMax)-log(1e-8+xMin));
                            getYUVtoRGB(smoothSaliency[i]>0, Y, 255.0f, 255.0f, colors[3*i], colors[3*i+1], colors[3*i+2]);
                        }
                        break;
                    }
            case 4: {
                        for(int i = 0; i < vertexCntHere; i++)
                            colors[3*i+0] = simplifiedNormals[3*i+0],
                            colors[3*i+1] = simplifiedNormals[3*i+1],
                            colors[3*i+2] = simplifiedNormals[3*i+2];
                        break;
                    }
        }
        glBufferData (
            GL_ARRAY_BUFFER,
            3 * vertexCntHere * sizeof (GLfloat),
            colors,
            GL_STATIC_DRAW
        );
        glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
        glEnableVertexAttribArray (1);
    }
}