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); } } }
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; }