Beispiel #1
0
void RenderTask::releaseTiles() {
  m_rendererImp->m_rasterPool.releaseRaster(m_tileA.getRaster());
  m_tileA.setRaster(TRasterP());
  if (m_fieldRender || m_stereoscopic) {
    m_rendererImp->m_rasterPool.releaseRaster(m_tileB.getRaster());
    m_tileB.setRaster(TRasterP());
  }
}
void Particles_Engine::render_particles(
    TFlash *flash, TTile *tile, std::vector<TRasterFxPort *> part_ports,
    const TRenderSettings &ri, TDimension &p_size, TPointD &p_offset,
    std::map<int, TRasterFxPort *> ctrl_ports, std::vector<TLevelP> partLevel,
    float dpi, int curr_frame, int shrink, double startx, double starty,
    double endx, double endy, std::vector<int> last_frame, unsigned long fxId) {
  int frame, startframe, intpart = 0, level_n = 0;
  struct particles_values values;
  double dpicorr = dpi * 0.01, fractpart = 0, dpicorr_shrinked = 0,
         opacity_range = 0;
  bool random_level    = false;
  level_n              = part_ports.size();

  bool isPrecomputingEnabled = false;
  {
    TRenderer renderer(TRenderer::instance());
    isPrecomputingEnabled =
        (renderer && renderer.isPrecomputingEnabled()) ? true : false;
  }

  memset(&values, 0, sizeof(values));
  /*- 現在のフレームでの各種パラメータを得る -*/
  fill_value_struct(values, m_frame);
  /*- 不透明度の範囲(透明〜不透明を 0〜1 に正規化)-*/
  opacity_range = (values.opacity_val.second - values.opacity_val.first) * 0.01;
  /*- 開始フレーム -*/
  startframe = (int)values.startpos_val;
  if (values.unit_val == ParticlesFx::UNIT_SMALL_INCH)
    dpicorr_shrinked = dpicorr / shrink;
  else
    dpicorr_shrinked = dpi / shrink;

  std::map<std::pair<int, int>, double> partScales;
  curr_frame = curr_frame / values.step_val;

  ParticlesManager *pc = ParticlesManager::instance();

  // Retrieve the last rolled frame
  ParticlesManager::FrameData *particlesData = pc->data(fxId);

  std::list<Particle> myParticles;
  TRandom myRandom;
  values.random_val  = &myRandom;
  myRandom           = m_parent->randseed_val->getValue();
  int totalparticles = 0;

  int pcFrame = particlesData->m_frame;
  if (pcFrame > curr_frame) {
    // Clear stored particlesData
    particlesData->clear();
    pcFrame = particlesData->m_frame;
  } else if (pcFrame >= startframe - 1) {
    myParticles    = particlesData->m_particles;
    myRandom       = particlesData->m_random;
    totalparticles = particlesData->m_totalParticles;
  }
  /*- スタートからカレントフレームまでループ -*/
  for (frame = startframe - 1; frame <= curr_frame; ++frame) {
    int dist_frame = curr_frame - frame;
    /*-
     * ループ内の現在のフレームでのパラメータを取得。スタートが負ならフレーム=0のときの値を格納
     * -*/
    fill_value_struct(values, frame < 0 ? 0 : frame * values.step_val);
    /*- パラメータの正規化 -*/
    normalize_values(values, ri);
    /*- maxnum_valは"birth_rate"のパラメータ -*/
    intpart = (int)values.maxnum_val;
    /*-
     * /birth_rateが小数だったとき、各フレームの小数部分を足しこんだ結果の整数部分をintpartに渡す。
     * -*/
    fractpart = fractpart + values.maxnum_val - intpart;
    if ((int)fractpart) {
      values.maxnum_val += (int)fractpart;
      fractpart = fractpart - (int)fractpart;
    }

    std::map<int, TTile *> porttiles;

    // Perform the roll
    /*- RenderSettingsを複製して現在のフレームの計算用にする -*/
    TRenderSettings riAux(ri);
    riAux.m_affine = TAffine();
    riAux.m_bpp    = 32;

    int r_frame;  // Useful in case of negative roll frames
    if (frame < 0)
      r_frame = 0;
    else
      r_frame = frame;
    /*- 出力画像のバウンディングボックス -*/
    TRectD outTileBBox(tile->m_pos, TDimensionD(tile->getRaster()->getLx(),
                                                tile->getRaster()->getLy()));
    /*- Controlに刺さっている各ポートについて -*/
    for (std::map<int, TRasterFxPort *>::iterator it = ctrl_ports.begin();
         it != ctrl_ports.end(); ++it) {
      TTile *tmp;
      /*- ポートが接続されていて、Fx内で実際に使用されていたら -*/
      if ((it->second)->isConnected() && port_is_used(it->first, values)) {
        TRectD bbox;
        (*(it->second))->getBBox(r_frame, bbox, riAux);
        /*- 素材が存在する場合、portTilesにコントロール画像タイルを格納 -*/
        if (!bbox.isEmpty()) {
          if (bbox == TConsts::infiniteRectD)  // There could be an infinite
                                               // bbox - deal with it
            bbox = ri.m_affine.inv() * outTileBBox;

          if (frame <= pcFrame) {
            // This frame will not actually be rolled. However, it was
            // dryComputed - so, declare the same here.
            (*it->second)->dryCompute(bbox, r_frame, riAux);
          } else {
            tmp = new TTile;

            if (isPrecomputingEnabled)
              (*it->second)
                  ->allocateAndCompute(*tmp, bbox.getP00(),
                                       convert(bbox).getSize(), 0, r_frame,
                                       riAux);
            else {
              std::string alias =
                  "CTRL: " + (*(it->second))->getAlias(r_frame, riAux);
              TRasterImageP rimg = TImageCache::instance()->get(alias, false);

              if (rimg) {
                tmp->m_pos = bbox.getP00();
                tmp->setRaster(rimg->getRaster());
              } else {
                (*it->second)
                    ->allocateAndCompute(*tmp, bbox.getP00(),
                                         convert(bbox).getSize(), 0, r_frame,
                                         riAux);

                addRenderCache(alias, TRasterImageP(tmp->getRaster()));
              }
            }

            porttiles[it->first] = tmp;
          }
        }
      }
    }

    if (frame > pcFrame) {
      // Invoke the actual rolling procedure
      roll_particles(tile, porttiles, riAux, myParticles, values, 0, 0, frame,
                     curr_frame, level_n, &random_level, 1, last_frame,
                     totalparticles);

      // Store the rolled data in the particles manager
      if (!particlesData->m_calculated ||
          particlesData->m_frame + particlesData->m_maxTrail < frame) {
        particlesData->m_frame     = frame;
        particlesData->m_particles = myParticles;
        particlesData->m_random    = myRandom;
        particlesData->buildMaxTrail();
        particlesData->m_calculated     = true;
        particlesData->m_totalParticles = totalparticles;
      }
    }

    // Render the particles if the distance from current frame is a trail
    // multiple
    if (frame >= startframe - 1 &&
        !(dist_frame %
          (values.trailstep_val > 1.0 ? (int)values.trailstep_val : 1))) {
      // Store the maximum particle size before the do_render cycle
      std::list<Particle>::iterator pt;
      for (pt = myParticles.begin(); pt != myParticles.end(); ++pt) {
        Particle &part = *pt;
        int ndx        = part.frame % last_frame[part.level];
        std::pair<int, int> ndxPair(part.level, ndx);

        std::map<std::pair<int, int>, double>::iterator it =
            partScales.find(ndxPair);

        if (it != partScales.end())
          it->second = std::max(part.scale, it->second);
        else
          partScales[ndxPair] = part.scale;
      }

      if (values.toplayer_val == ParticlesFx::TOP_SMALLER ||
          values.toplayer_val == ParticlesFx::TOP_BIGGER)
        myParticles.sort(ComparebySize());

      if (values.toplayer_val == ParticlesFx::TOP_SMALLER) {
        std::list<Particle>::iterator pt;
        for (pt = myParticles.begin(); pt != myParticles.end(); ++pt) {
          Particle &part = *pt;
          if (dist_frame <= part.trail && part.scale && part.lifetime > 0 &&
              part.lifetime <=
                  part.genlifetime)  // This last... shouldn't always be?
          {
            do_render(flash, &part, tile, part_ports, porttiles, ri, p_size,
                      p_offset, last_frame[part.level], partLevel, values,
                      opacity_range, dist_frame, partScales);
          }
        }
      } else {
        std::list<Particle>::reverse_iterator pt;
        for (pt = myParticles.rbegin(); pt != myParticles.rend(); ++pt) {
          Particle &part = *pt;
          if (dist_frame <= part.trail && part.scale && part.lifetime > 0 &&
              part.lifetime <= part.genlifetime)  // Same here..?
          {
            do_render(flash, &part, tile, part_ports, porttiles, ri, p_size,
                      p_offset, last_frame[part.level], partLevel, values,
                      opacity_range, dist_frame, partScales);
          }
        }
      }
    }

    std::map<int, TTile *>::iterator it;
    for (it = porttiles.begin(); it != porttiles.end(); ++it) delete it->second;
  }
}
	void doCompute(TTile &tile, double frame, const TRenderSettings &info)
	{
		bool isWarped = m_warped.isConnected();

		if (!isWarped)
			return;

		if (fabs(m_intensity->getValue(frame)) < 0.01) {
			m_warped->compute(tile, frame, info);
			return;
		}

		int shrink = (info.m_shrinkX + info.m_shrinkY) / 2;
		double scale = sqrt(fabs(info.m_affine.det()));
		double gridStep = 1.5 * m_gridStep->getValue(frame);

		WarpParams params;
		params.m_intensity = m_intensity->getValue(frame) / gridStep;
		params.m_warperScale = scale * gridStep;
		params.m_sharpen = m_sharpen->getValue();
		params.m_shrink = shrink;
		double evolution = m_evol->getValue(frame);
		double size = 100.0 / info.m_shrinkX;
		TPointD pos(m_posx->getValue(frame), m_posy->getValue(frame));

		//The warper is calculated on a standard reference, with fixed dpi. This makes sure
		//that the lattice created for the warp does not depend on camera transforms and resolution.
		TRenderSettings warperInfo(info);
		double warperScaleFactor = 1.0 / params.m_warperScale;
		warperInfo.m_affine = TScale(warperScaleFactor) * info.m_affine;

		//Retrieve tile's geometry
		TRectD tileRect;
		{
			TRasterP tileRas = tile.getRaster();
			tileRect = TRectD(tile.m_pos, TDimensionD(tileRas->getLx(), tileRas->getLy()));
		}

		//Build the compute rect
		TRectD warpedBox, warpedComputeRect, tileComputeRect;
		m_warped->getBBox(frame, warpedBox, info);

		getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, tileRect, params);

		if (tileComputeRect.getLx() <= 0 || tileComputeRect.getLy() <= 0)
			return;
		if (warpedComputeRect.getLx() <= 0 || warpedComputeRect.getLy() <= 0)
			return;

		TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect);
		double warperEnlargement = getWarperEnlargement(params);
		warperComputeRect = warperComputeRect.enlarge(warperEnlargement);
		warperComputeRect.x0 = tfloor(warperComputeRect.x0);
		warperComputeRect.y0 = tfloor(warperComputeRect.y0);
		warperComputeRect.x1 = tceil(warperComputeRect.x1);
		warperComputeRect.y1 = tceil(warperComputeRect.y1);

		//Compute the warped tile
		TTile tileIn;
		m_warped->allocateAndCompute(tileIn, warpedComputeRect.getP00(),
									 TDimension(warpedComputeRect.getLx(), warpedComputeRect.getLy()),
									 tile.getRaster(), frame, info);
		TRasterP rasIn = tileIn.getRaster();

		//Compute the warper tile
		TSpectrum::ColorKey colors[] = {
			TSpectrum::ColorKey(0, TPixel32::White),
			TSpectrum::ColorKey(1, TPixel32::Black)};

		TSpectrumParamP cloudscolors = TSpectrumParamP(tArrayCount(colors), colors);

		//Build the warper
		warperInfo.m_affine = warperInfo.m_affine;
		TAffine aff = warperInfo.m_affine.inv();

		TTile warperTile;
		TRasterP rasWarper = rasIn->create(warperComputeRect.getLx(), warperComputeRect.getLy());
		warperTile.m_pos = warperComputeRect.getP00();
		warperTile.setRaster(rasWarper);

		{
			TRenderSettings info2(warperInfo);

			//Now, separate the part of the affine the Fx can handle from the rest.
			TAffine fxHandledAffine = handledAffine(warperInfo, frame);
			info2.m_affine = fxHandledAffine;

			TAffine aff = warperInfo.m_affine * fxHandledAffine.inv();
			aff.a13 /= warperInfo.m_shrinkX;
			aff.a23 /= warperInfo.m_shrinkY;

			TRectD rectIn = aff.inv() * warperComputeRect;

			//rectIn = rectIn.enlarge(getResampleFilterRadius(info));  //Needed to counter the resample filter

			TRect rectInI(tfloor(rectIn.x0), tfloor(rectIn.y0), tceil(rectIn.x1) - 1, tceil(rectIn.y1) - 1);

			// rasIn e' un raster dello stesso tipo di tile.getRaster()

			TTile auxtile(warperTile.getRaster()->create(rectInI.getLx(), rectInI.getLy()), convert(rectInI.getP00()));

			TPointD mypos(auxtile.m_pos - pos);

			double scale2 = sqrt(fabs(info2.m_affine.det()));
			doClouds(auxtile.getRaster(), cloudscolors, mypos, evolution, size, 0.0, 1.0, PNOISE_CLOUDS, scale2, frame);

			info2.m_affine = aff;
			TRasterFx::applyAffine(warperTile, auxtile, info2);
		}

		//Warp
		TPointD db;
		TRect rasComputeRectI(convert(tileComputeRect - tileRect.getP00(), db));
		TRasterP tileRas = tile.getRaster()->extract(rasComputeRectI);

		TPointD rasInPos(warpedComputeRect.getP00() - tileComputeRect.getP00());
		TPointD warperPos((TScale(params.m_warperScale) * warperComputeRect.getP00()) - tileComputeRect.getP00());
		warp(tileRas, rasIn, rasWarper, rasInPos, warperPos, params);
	}
Beispiel #4
0
void RenderTask::buildTile(TTile &tile) {
  tile.m_pos = m_framePos;
  tile.setRaster(
      m_rendererImp->m_rasterPool.getRaster(m_frameSize, m_info.m_bpp));
}