Пример #1
0
void GUI::FillDoodadPreviewBuffer()
{
	DoodadBrush* brush = dynamic_cast<DoodadBrush*>(current_brush);
	if(!brush)
		return;

	doodad_buffer_map->clear();

	if(brush->isEmpty(GetBrushVariation()))
		return;

	int object_count = 0;
	int area;
	if(GetBrushShape() == BRUSHSHAPE_SQUARE) {
		area = 2*GetBrushSize();
		area = area*area + 1;
	} else {
		if(GetBrushSize() == 1) {
			// There is a huge deviation here with the other formula.
			area = 5;
		} else {
			area = int(0.5 + GetBrushSize() * GetBrushSize() * PI);
		}
	}
	const int object_range = (use_custom_thickness? int(area*custom_thickness_mod) : brush->getThickness() * area / max(1, brush->getThicknessCeiling()));
	const int final_object_count = max(1, object_range + random(object_range));

	Position center_pos(0x8000, 0x8000, 0x8);

	if(brush_size > 0 && !brush->oneSizeFitsAll()) {
		while(object_count < final_object_count) {
			int retries = 0;
			bool exit = false;

			// Try to place objects 5 times
			while(retries < 5 && !exit) {

				int pos_retries = 0;
				int xpos = 0, ypos = 0;
				bool found_pos = false;
				if(GetBrushShape() == BRUSHSHAPE_CIRCLE) {
					while(pos_retries < 5 && !found_pos) {
						xpos = random(-brush_size, brush_size);
						ypos = random(-brush_size, brush_size);
						float distance = sqrt(float(xpos*xpos) + float(ypos*ypos));
						if(distance < g_gui.GetBrushSize() + 0.005) {
							found_pos = true;
						} else {
							++pos_retries;
						}
					}
				} else {
					found_pos = true;
					xpos = random(-brush_size, brush_size);
					ypos = random(-brush_size, brush_size);
				}

				if(!found_pos) {
					++retries;
					continue;
				}

				// Decide whether the zone should have a composite or several single objects.
				bool fail = false;
				if(random(brush->getTotalChance(GetBrushVariation())) <= brush->getCompositeChance(GetBrushVariation())) {
					// Composite
					const CompositeTileList& composites = brush->getComposite(GetBrushVariation());

					// Figure out if the placement is valid
					for(CompositeTileList::const_iterator composite_iter = composites.begin();
							composite_iter != composites.end();
							++composite_iter)
					{
						Position pos = center_pos + composite_iter->first + Position(xpos, ypos, 0);
						if(Tile* tile = doodad_buffer_map->getTile(pos)) {
							if(tile->size() > 0) {
								fail = true;
								break;
							}
						}
					}
					if(fail) {
						++retries;
						break;
					}

					// Transfer items to the stack
					for(CompositeTileList::const_iterator composite_iter = composites.begin();
							composite_iter != composites.end();
							++composite_iter)
					{
						Position pos = center_pos + composite_iter->first + Position(xpos, ypos, 0);
						const ItemVector& items = composite_iter->second;
						Tile* tile = doodad_buffer_map->getTile(pos);

						if(!tile)
							tile = doodad_buffer_map->allocator(doodad_buffer_map->createTileL(pos));

						for(ItemVector::const_iterator item_iter = items.begin();
								item_iter != items.end();
								++item_iter)
						{
							tile->addItem((*item_iter)->deepCopy());
						}
						doodad_buffer_map->setTile(tile->getPosition(), tile);
					}
					exit = true;
				} else if(brush->hasSingleObjects(GetBrushVariation())) {
					Position pos = center_pos + Position(xpos, ypos, 0);
					Tile* tile = doodad_buffer_map->getTile(pos);
					if(tile) {
						if(tile->size() > 0) {
							fail = true;
							break;
						}
					} else {
						tile = doodad_buffer_map->allocator(doodad_buffer_map->createTileL(pos));
					}
					int variation = GetBrushVariation();
					brush->draw(doodad_buffer_map, tile, &variation);
					//std::cout << "\tpos: " << tile->getPosition() << std::endl;
					doodad_buffer_map->setTile(tile->getPosition(), tile);
					exit = true;
				}
				if(fail) {
					++retries;
					break;
				}
			}
			++object_count;
		}
	} else {
		if(brush->hasCompositeObjects(GetBrushVariation()) &&
				random(brush->getTotalChance(GetBrushVariation())) <= brush->getCompositeChance(GetBrushVariation())) {
			// Composite
			const CompositeTileList& composites = brush->getComposite(GetBrushVariation());

			// All placement is valid...

			// Transfer items to the buffer
			for(CompositeTileList::const_iterator composite_iter = composites.begin();
					composite_iter != composites.end();
					++composite_iter) {
				Position pos = center_pos + composite_iter->first;
				const ItemVector& items = composite_iter->second;
				Tile* tile = doodad_buffer_map->allocator(doodad_buffer_map->createTileL(pos));
				//std::cout << pos << " = " << center_pos << " + " << buffer_tile->getPosition() << std::endl;

				for(ItemVector::const_iterator item_iter = items.begin();
						item_iter != items.end();
						++item_iter)
				{
					tile->addItem((*item_iter)->deepCopy());
				}
				doodad_buffer_map->setTile(tile->getPosition(), tile);
			}
		} else if(brush->hasSingleObjects(GetBrushVariation())) {
			Tile* tile = doodad_buffer_map->allocator(doodad_buffer_map->createTileL(center_pos));
			int variation = GetBrushVariation();
			brush->draw(doodad_buffer_map, tile, &variation);
			doodad_buffer_map->setTile(center_pos, tile);
		}
	}
}
Пример #2
0
	bool LensFlareSceneObject::MainThreadUpdate(float /*app_time*/, float /*elapsed_time*/)
	{
		float const FLARE_RENDERANGLE = 0.9f;
		float const FLARE_SCALEAMOUNT = 0.2f;

		App3DFramework const & app = Context::Instance().AppInstance();
		Camera const & camera = app.ActiveCamera();

		float4x4 const & view = camera.ViewMatrix();
		float4x4 const & proj = camera.ProjMatrix();

		float3 sun_vec = MathLib::normalize(dir_);
		float3 const & view_vec = camera.ForwardVec();

		float angle = MathLib::dot(view_vec, sun_vec);

		// update flare
		if (angle > FLARE_RENDERANGLE)
		{
			lf_visible_ = true;

			// get angle amount by current angle
			float angle_amount = 1 - (1 - angle) / (1 - FLARE_RENDERANGLE);	// convert angle to percent 
			float inv_angle_amount = std::max(0.85f, (1 - angle) / (1 - FLARE_RENDERANGLE));

			float alpha_fac;
			if (angle_amount < 0.5f)
			{
				alpha_fac = angle_amount;
			}
			else
			{
				alpha_fac = 1 - angle_amount;
			}

			// calculate flare pos
			float2 center_pos(0, 0);
			float3 sun_vec_es = MathLib::transform_normal(dir_, view);
			float3 sun_pos_es = camera.FarPlane() / sun_vec_es.z() * sun_vec_es;
			float2 axis_vec = MathLib::transform_coord(sun_pos_es, proj);

			// update flare pos and scale matrix by pos and angle amount
			std::vector<float3> flare_param(SUN_FLARENUM);
			for (int flare = 0; flare < SUN_FLARENUM; ++ flare)
			{
				float2 flare_pos = center_pos + (flare - SUN_FLARENUM * 0.2f) / ((SUN_FLARENUM - 1.0f) * 1.5f) * axis_vec;
				float scale_fac = FLARE_SCALEAMOUNT * inv_angle_amount * ((SUN_FLARENUM - flare) / (SUN_FLARENUM - 1.0f));

				flare_param[flare] = float3(flare_pos.x(), flare_pos.y(), scale_fac);
			}

			checked_pointer_cast<LensFlareRenderable>(renderable_)->FlareParam(flare_param, alpha_fac);
		}
		else
		{
			lf_visible_ = false;
		}

		this->Visible(true);

		return false;
	}