void main (void) { gl_FragColor = clamp(effectColorAdd + texture2D(diffuseTextureUnit, gl_PointCoord) * fragColor * effectColorMul, 0.0, 1.0); }
float viewfieldx(int x) { return x <= 100 ? clamp((VIEWMIN+(VIEWMAX-VIEWMIN))/100.f*float(x), float(VIEWMIN), float(VIEWMAX)) : float(VIEWMAX); }
template <typename T> GLM_FUNC_QUALIFIER T saturate(T x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
int CMenus::PopupFilter(CMenus *pMenus, CUIRect View) { CUIRect ServerFilter = View, FilterHeader; const float FontSize = 12.0f; // slected filter CBrowserFilter *pFilter = &pMenus->m_lFilters[pMenus->m_SelectedFilter]; CServerFilterInfo FilterInfo; pFilter->GetFilter(&FilterInfo); // server filter ServerFilter.HSplitTop(ms_ListheaderHeight, &FilterHeader, &ServerFilter); pMenus->RenderTools()->DrawUIRect(&FilterHeader, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f); pMenus->RenderTools()->DrawUIRect(&ServerFilter, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f); pMenus->UI()->DoLabelScaled(&FilterHeader, Localize("Server filter"), FontSize+2.0f, CUI::ALIGN_CENTER); CUIRect Button; ServerFilter.VSplitLeft(5.0f, 0, &ServerFilter); ServerFilter.Margin(3.0f, &ServerFilter); ServerFilter.VMargin(5.0f, &ServerFilter); int NewSortHash = FilterInfo.m_SortHash; ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); static int s_BrFilterEmpty = 0; if(pMenus->DoButton_CheckBox(&s_BrFilterEmpty, Localize("Has people playing"), FilterInfo.m_SortHash&IServerBrowser::FILTER_EMPTY, &Button)) NewSortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_EMPTY; ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); static int s_BrFilterSpectators = 0; if(pMenus->DoButton_CheckBox(&s_BrFilterSpectators, Localize("Count players only"), FilterInfo.m_SortHash&IServerBrowser::FILTER_SPECTATORS, &Button)) NewSortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_SPECTATORS; ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); static int s_BrFilterFull = 0; if(pMenus->DoButton_CheckBox(&s_BrFilterFull, Localize("Server not full"), FilterInfo.m_SortHash&IServerBrowser::FILTER_FULL, &Button)) NewSortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_FULL; ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); static int s_BrFilterFriends = 0; if(pMenus->DoButton_CheckBox(&s_BrFilterFriends, Localize("Show friends only"), FilterInfo.m_SortHash&IServerBrowser::FILTER_FRIENDS, &Button)) NewSortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_FRIENDS; ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); static int s_BrFilterPw = 0; if(pMenus->DoButton_CheckBox(&s_BrFilterPw, Localize("No password"), FilterInfo.m_SortHash&IServerBrowser::FILTER_PW, &Button)) NewSortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_PW; ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); static int s_BrFilterCompatversion = 0; if(pMenus->DoButton_CheckBox(&s_BrFilterCompatversion, Localize("Compatible version"), FilterInfo.m_SortHash&IServerBrowser::FILTER_COMPAT_VERSION, &Button)) NewSortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_COMPAT_VERSION; ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); static int s_BrFilterPure = 0; if(pMenus->DoButton_CheckBox(&s_BrFilterPure, Localize("Standard gametype"), FilterInfo.m_SortHash&IServerBrowser::FILTER_PURE, &Button)) NewSortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_PURE; ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); static int s_BrFilterPureMap = 0; if(pMenus->DoButton_CheckBox(&s_BrFilterPureMap, Localize("Standard map"), FilterInfo.m_SortHash&IServerBrowser::FILTER_PURE_MAP, &Button)) NewSortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_PURE_MAP; ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); static int s_BrFilterGametypeStrict = 0; if(pMenus->DoButton_CheckBox(&s_BrFilterGametypeStrict, Localize("Strict gametype filter"), FilterInfo.m_SortHash&IServerBrowser::FILTER_GAMETYPE_STRICT, &Button)) NewSortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_GAMETYPE_STRICT; if(FilterInfo.m_SortHash != NewSortHash) { FilterInfo.m_SortHash = NewSortHash; pFilter->SetFilter(&FilterInfo); } ServerFilter.HSplitTop(5.0f, 0, &ServerFilter); ServerFilter.HSplitTop(19.0f, &Button, &ServerFilter); pMenus->UI()->DoLabelScaled(&Button, Localize("Game types:"), FontSize, CUI::ALIGN_LEFT); Button.VSplitRight(60.0f, 0, &Button); ServerFilter.HSplitTop(3.0f, 0, &ServerFilter); static float Offset = 0.0f; static int s_BrFilterGametype = 0; if(pMenus->DoEditBox(&s_BrFilterGametype, &Button, FilterInfo.m_aGametype, sizeof(FilterInfo.m_aGametype), FontSize, &Offset)) pFilter->SetFilter(&FilterInfo); { ServerFilter.HSplitTop(19.0f, &Button, &ServerFilter); CUIRect EditBox; Button.VSplitRight(60.0f, &Button, &EditBox); pMenus->UI()->DoLabelScaled(&Button, Localize("Maximum ping:"), FontSize, CUI::ALIGN_LEFT); char aBuf[5]; str_format(aBuf, sizeof(aBuf), "%d", FilterInfo.m_Ping); static float Offset = 0.0f; static int s_BrFilterPing = 0; pMenus->DoEditBox(&s_BrFilterPing, &EditBox, aBuf, sizeof(aBuf), FontSize, &Offset); int NewPing = clamp(str_toint(aBuf), 0, 999); if(NewPing != FilterInfo.m_Ping) { FilterInfo.m_Ping = NewPing; pFilter->SetFilter(&FilterInfo); } } // server address ServerFilter.HSplitTop(3.0f, 0, &ServerFilter); ServerFilter.HSplitTop(19.0f, &Button, &ServerFilter); pMenus->UI()->DoLabelScaled(&Button, Localize("Server address:"), FontSize, CUI::ALIGN_LEFT); Button.VSplitRight(60.0f, 0, &Button); static float OffsetAddr = 0.0f; static int s_BrFilterServerAddress = 0; if(pMenus->DoEditBox(&s_BrFilterServerAddress, &Button, FilterInfo.m_aAddress, sizeof(FilterInfo.m_aAddress), FontSize, &OffsetAddr)) pFilter->SetFilter(&FilterInfo); // player country { CUIRect Rect; ServerFilter.HSplitTop(3.0f, 0, &ServerFilter); ServerFilter.HSplitTop(26.0f, &Button, &ServerFilter); Button.VSplitRight(60.0f, &Button, &Rect); Button.HMargin(3.0f, &Button); static int s_BrFilterCountry = 0; if(pMenus->DoButton_CheckBox(&s_BrFilterCountry, Localize("Player country:"), FilterInfo.m_SortHash&IServerBrowser::FILTER_COUNTRY, &Button)) { FilterInfo.m_SortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_COUNTRY; pFilter->SetFilter(&FilterInfo); } float OldWidth = Rect.w; Rect.w = Rect.h*2; Rect.x += (OldWidth-Rect.w)/2.0f; vec4 Color(1.0f, 1.0f, 1.0f, FilterInfo.m_SortHash^IServerBrowser::FILTER_COUNTRY?1.0f: 0.5f); pMenus->m_pClient->m_pCountryFlags->Render(FilterInfo.m_Country, &Color, Rect.x, Rect.y, Rect.w, Rect.h); static int s_BrFilterCountryIndex = 0; if(FilterInfo.m_SortHash^IServerBrowser::FILTER_COUNTRY && pMenus->UI()->DoButtonLogic(&s_BrFilterCountryIndex, "", 0, &Rect)) pMenus->m_Popup = POPUP_COUNTRY; } return 0; }
void CBeam::InputColorBlueValue( inputdata_t &inputdata ) { int nNewColor = clamp( inputdata.value.Int(), 0, 255 ); SetColor( m_clrRender->r, m_clrRender->g, nNewColor ); }
//----------------------------------------------------------------------------- // This is called after sending this entity's recording state //----------------------------------------------------------------------------- void C_ParticleSmokeGrenade::CleanupToolRecordingState( KeyValues *msg ) { if ( !ToolsEnabled() ) return; BaseClass::CleanupToolRecordingState( msg ); m_SmokeTrail.CleanupToolRecordingState( msg ); // Generally, this is used to allow the entity to clean up // allocated state it put into the message, but here we're going // to use it to send particle system messages because we // know the grenade has been recorded at this point if ( !clienttools->IsInRecordingMode() ) return; // NOTE: Particle system destruction message will be sent by the particle effect itself. if ( m_bVolumeFilled && GetToolParticleEffectId() == TOOLPARTICLESYSTEMID_INVALID ) { // Needed for retriggering of the smoke grenade m_bVolumeFilled = false; int nId = AllocateToolParticleEffectId(); KeyValues *msg = new KeyValues( "ParticleSystem_Create" ); msg->SetString( "name", "C_ParticleSmokeGrenade" ); msg->SetInt( "id", nId ); msg->SetFloat( "time", gpGlobals->curtime ); KeyValues *pEmitter = msg->FindKey( "DmeSpriteEmitter", true ); pEmitter->SetInt( "count", NUM_PARTICLES_PER_DIMENSION * NUM_PARTICLES_PER_DIMENSION * NUM_PARTICLES_PER_DIMENSION ); pEmitter->SetFloat( "duration", 0 ); pEmitter->SetString( "material", "particle/particle_smokegrenade1" ); pEmitter->SetInt( "active", true ); KeyValues *pInitializers = pEmitter->FindKey( "initializers", true ); KeyValues *pPosition = pInitializers->FindKey( "DmeVoxelPositionInitializer", true ); pPosition->SetFloat( "centerx", m_SmokeBasePos.x ); pPosition->SetFloat( "centery", m_SmokeBasePos.y ); pPosition->SetFloat( "centerz", m_SmokeBasePos.z ); pPosition->SetFloat( "particlesPerDimension", m_xCount ); pPosition->SetFloat( "particleSpacing", m_SpacingRadius ); KeyValues *pLifetime = pInitializers->FindKey( "DmeRandomLifetimeInitializer", true ); pLifetime->SetFloat( "minLifetime", m_FadeEndTime ); pLifetime->SetFloat( "maxLifetime", m_FadeEndTime ); KeyValues *pVelocity = pInitializers->FindKey( "DmeAttachmentVelocityInitializer", true ); pVelocity->SetPtr( "entindex", (void*)entindex() ); pVelocity->SetFloat( "minRandomSpeed", 10 ); pVelocity->SetFloat( "maxRandomSpeed", 20 ); KeyValues *pRoll = pInitializers->FindKey( "DmeRandomRollInitializer", true ); pRoll->SetFloat( "minRoll", -6.0f ); pRoll->SetFloat( "maxRoll", 6.0f ); KeyValues *pRollSpeed = pInitializers->FindKey( "DmeRandomRollSpeedInitializer", true ); pRollSpeed->SetFloat( "minRollSpeed", -ROTATION_SPEED ); pRollSpeed->SetFloat( "maxRollSpeed", ROTATION_SPEED ); KeyValues *pColor = pInitializers->FindKey( "DmeRandomInterpolatedColorInitializer", true ); Color c1( clamp( m_MinColor.x * 255.0f, 0, 255 ), clamp( m_MinColor.y * 255.0f, 0, 255 ), clamp( m_MinColor.z * 255.0f, 0, 255 ), 255 ); Color c2( clamp( m_MaxColor.x * 255.0f, 0, 255 ), clamp( m_MaxColor.y * 255.0f, 0, 255 ), clamp( m_MaxColor.z * 255.0f, 0, 255 ), 255 ); pColor->SetColor( "color1", c1 ); pColor->SetColor( "color2", c2 ); KeyValues *pAlpha = pInitializers->FindKey( "DmeRandomAlphaInitializer", true ); pAlpha->SetInt( "minStartAlpha", 255 ); pAlpha->SetInt( "maxStartAlpha", 255 ); pAlpha->SetInt( "minEndAlpha", 0 ); pAlpha->SetInt( "maxEndAlpha", 0 ); KeyValues *pSize = pInitializers->FindKey( "DmeRandomSizeInitializer", true ); pSize->SetFloat( "minStartSize", SMOKEPARTICLE_SIZE ); pSize->SetFloat( "maxStartSize", SMOKEPARTICLE_SIZE ); pSize->SetFloat( "minEndSize", SMOKEPARTICLE_SIZE ); pSize->SetFloat( "maxEndSize", SMOKEPARTICLE_SIZE ); pInitializers->FindKey( "DmeSolidKillInitializer", true ); KeyValues *pUpdaters = pEmitter->FindKey( "updaters", true ); pUpdaters->FindKey( "DmeRollUpdater", true ); pUpdaters->FindKey( "DmeColorUpdater", true ); KeyValues *pAlphaCosineUpdater = pUpdaters->FindKey( "DmeAlphaCosineUpdater", true ); pAlphaCosineUpdater->SetFloat( "duration", m_FadeEndTime - m_FadeStartTime ); pUpdaters->FindKey( "DmeColorDynamicLightUpdater", true ); KeyValues *pSmokeGrenadeUpdater = pUpdaters->FindKey( "DmeSmokeGrenadeUpdater", true ); pSmokeGrenadeUpdater->SetFloat( "centerx", m_SmokeBasePos.x ); pSmokeGrenadeUpdater->SetFloat( "centery", m_SmokeBasePos.y ); pSmokeGrenadeUpdater->SetFloat( "centerz", m_SmokeBasePos.z ); pSmokeGrenadeUpdater->SetFloat( "particlesPerDimension", m_xCount ); pSmokeGrenadeUpdater->SetFloat( "particleSpacing", m_SpacingRadius ); pSmokeGrenadeUpdater->SetFloat( "radiusExpandTime", SMOKESPHERE_EXPAND_TIME ); pSmokeGrenadeUpdater->SetFloat( "cutoffFraction", 0.7f ); ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg ); msg->deleteThis(); } }
float AI_Car_Experimental::RampBetween(float val, float startat, float endat) { assert(endat > startat); return (clamp(val,startat,endat)-startat)/(endat-startat); }
inline void Colour::setGreen(double g) { _g = clamp(g, 0.0, 1.0); }
//----------------------------------------------------------------------------- // Parses the key-value pairs in the detail.rad file //----------------------------------------------------------------------------- static void ParseDetailGroup( int detailId, KeyValues* pGroupKeyValues ) { // Sort the group by alpha float alpha = pGroupKeyValues->GetFloat( "alpha", 1.0f ); int i = s_DetailObjectDict[detailId].m_Groups.Count(); while ( --i >= 0 ) { if (alpha > s_DetailObjectDict[detailId].m_Groups[i].m_Alpha) break; } // Insert after the first guy who's more transparent that we are! i = s_DetailObjectDict[detailId].m_Groups.InsertAfter(i); DetailObjectGroup_t& group = s_DetailObjectDict[detailId].m_Groups[i]; group.m_Alpha = alpha; // Add in all the model groups KeyValues* pIter = pGroupKeyValues->GetFirstSubKey(); float totalAmount = 0.0f; while( pIter ) { if (pIter->GetFirstSubKey()) { int i = group.m_Models.AddToTail(); DetailModel_t &model = group.m_Models[i]; model.m_ModelName = pIter->GetString( "model", 0 ); if (model.m_ModelName != UTL_INVAL_SYMBOL) { model.m_Type = DETAIL_PROP_TYPE_MODEL; } else { const char *pSpriteData = pIter->GetString( "sprite", 0 ); if (pSpriteData) { const char *pProcModelType = pIter->GetString( "sprite_shape", 0 ); if ( pProcModelType ) { if ( !Q_stricmp( pProcModelType, "cross" ) ) { model.m_Type = DETAIL_PROP_TYPE_SHAPE_CROSS; } else if ( !Q_stricmp( pProcModelType, "tri" ) ) { model.m_Type = DETAIL_PROP_TYPE_SHAPE_TRI; } else model.m_Type = DETAIL_PROP_TYPE_SPRITE; } else { // card sprite model.m_Type = DETAIL_PROP_TYPE_SPRITE; } model.m_Tex[0].Init(); model.m_Tex[1].Init(); float x = 0, y = 0, flWidth = 64, flHeight = 64, flTextureSize = 512; int nValid = sscanf( pSpriteData, "%f %f %f %f %f", &x, &y, &flWidth, &flHeight, &flTextureSize ); if ( (nValid != 5) || (flTextureSize == 0) ) { Error( "Invalid arguments to \"sprite\" in detail.vbsp!\n" ); } model.m_Tex[0].x = ( x + 0.5f ) / flTextureSize; model.m_Tex[0].y = ( y + 0.5f ) / flTextureSize; model.m_Tex[1].x = ( x + flWidth - 0.5f ) / flTextureSize; model.m_Tex[1].y = ( y + flHeight - 0.5f ) / flTextureSize; model.m_Pos[0].Init( -10, 20 ); model.m_Pos[1].Init( 10, 0 ); pSpriteData = pIter->GetString( "spritesize", 0 ); if (pSpriteData) { sscanf( pSpriteData, "%f %f %f %f", &x, &y, &flWidth, &flHeight ); float ox = flWidth * x; float oy = flHeight * y; model.m_Pos[0].x = -ox; model.m_Pos[0].y = flHeight - oy; model.m_Pos[1].x = flWidth - ox; model.m_Pos[1].y = -oy; } model.m_flRandomScaleStdDev = pIter->GetFloat( "spriterandomscale", 0.0f ); // sway is a percent of max sway, cl_detail_max_sway float flSway = clamp( pIter->GetFloat( "sway", 0.0f ), 0.0, 1.0 ); model.m_SwayAmount = (unsigned char)( 255.0 * flSway ); // shape angle // for the tri shape, this is the angle each side is fanned out model.m_ShapeAngle = pIter->GetInt( "shape_angle", 0 ); // shape size // for the tri shape, this is the distance from the origin to the center of a side float flShapeSize = clamp( pIter->GetFloat( "shape_size", 0.0f ), 0.0, 1.0 ); model.m_ShapeSize = (unsigned char)( 255.0 * flShapeSize ); } } model.m_Amount = pIter->GetFloat( "amount", 1.0 ) + totalAmount; totalAmount = model.m_Amount; model.m_Flags = 0; if (pIter->GetInt( "upright", 0 )) { model.m_Flags |= MODELFLAG_UPRIGHT; } // These are used to prevent emission on steep surfaces float minAngle = pIter->GetFloat( "minAngle", 180 ); float maxAngle = pIter->GetFloat( "maxAngle", 180 ); model.m_MinCosAngle = cos(minAngle * M_PI / 180.f); model.m_MaxCosAngle = cos(maxAngle * M_PI / 180.f); model.m_Orientation = pIter->GetInt( "detailOrientation", 0 ); // Make sure minAngle < maxAngle if ( model.m_MinCosAngle < model.m_MaxCosAngle) { model.m_MinCosAngle = model.m_MaxCosAngle; } } pIter = pIter->GetNextKey(); } // renormalize the amount if the total > 1 if (totalAmount > 1.0f) { for (i = 0; i < group.m_Models.Count(); ++i) { group.m_Models[i].m_Amount /= totalAmount; } } }
inline void Colour::setBlue(double b) { _b = clamp(b, 0.0, 1.0); }
inline void Colour::setRed(double r) { _r = clamp(r, 0.0, 1.0); }
void player::consume_effects( const item &food ) { if( !food.is_comestible() ) { debugmsg( "called player::consume_effects with non-comestible" ); return; } const auto &comest = *food.type->comestible; const int capacity = stomach_capacity(); if( has_trait( trait_id( "THRESH_PLANT" ) ) && food.type->can_use( "PLANTBLECH" ) ) { // Just keep nutrition capped, to prevent vomiting cap_nutrition_thirst( *this, capacity, true, true ); return; } if( ( has_trait( trait_id( "HERBIVORE" ) ) || has_trait( trait_id( "RUMINANT" ) ) ) && food.has_any_flag( herbivore_blacklist ) ) { // No good can come of this. return; } // Rotten food causes health loss const float relative_rot = food.get_relative_rot(); if( relative_rot > 1.0f && !has_trait( trait_id( "SAPROPHAGE" ) ) && !has_trait( trait_id( "SAPROVORE" ) ) && !has_bionic( bio_digestion ) ) { const float rottedness = clamp( 2 * relative_rot - 2.0f, 0.1f, 1.0f ); // ~-1 health per 1 nutrition at halfway-rotten-away, ~0 at "just got rotten" // But always round down int h_loss = -rottedness * comest.nutr; mod_healthy_mod( h_loss, -200 ); add_msg( m_debug, "%d health from %0.2f%% rotten food", h_loss, rottedness ); } const auto nutr = nutrition_for( food ); mod_hunger( -nutr ); mod_thirst( -comest.quench ); mod_stomach_food( nutr ); mod_stomach_water( comest.quench ); if( comest.healthy != 0 ) { // Effectively no cap on health modifiers from food mod_healthy_mod( comest.healthy, ( comest.healthy >= 0 ) ? 200 : -200 ); } if( comest.stim != 0 && ( abs( stim ) < ( abs( comest.stim ) * 3 ) || sgn( stim ) != sgn( comest.stim ) ) ) { if( comest.stim < 0 ) { stim = std::max( comest.stim * 3, stim + comest.stim ); } else { stim = std::min( comest.stim * 3, stim + comest.stim ); } } add_addiction( comest.add, comest.addict ); if( addiction_craving( comest.add ) != MORALE_NULL ) { rem_morale( addiction_craving( comest.add ) ); } // Morale is in minutes int morale_time = HOURS( 2 ) / MINUTES( 1 ); if( food.has_flag( "HOT" ) && food.has_flag( "EATEN_HOT" ) ) { morale_time = HOURS( 3 ) / MINUTES( 1 ); int clamped_nutr = std::max( 5, std::min( 20, nutr / 10 ) ); add_morale( MORALE_FOOD_HOT, clamped_nutr, 20, morale_time, morale_time / 2 ); } std::pair<int, int> fun = fun_for( food ); if( fun.first < 0 ) { add_morale( MORALE_FOOD_BAD, fun.first, fun.second, morale_time, morale_time / 2, false, food.type ); } else if( fun.first > 0 ) { add_morale( MORALE_FOOD_GOOD, fun.first, fun.second, morale_time, morale_time / 2, false, food.type ); } const bool hibernate = has_active_mutation( trait_id( "HIBERNATE" ) ); if( hibernate ) { if( ( nutr > 0 && get_hunger() < -60 ) || ( comest.quench > 0 && get_thirst() < -60 ) ) { //Tell the player what's going on add_msg_if_player( _( "You gorge yourself, preparing to hibernate." ) ); if( one_in( 2 ) ) { //50% chance of the food tiring you mod_fatigue( nutr ); } } if( ( nutr > 0 && get_hunger() < -200 ) || ( comest.quench > 0 && get_thirst() < -200 ) ) { //Hibernation should cut burn to 60/day add_msg_if_player( _( "You feel stocked for a day or two. Got your bed all ready and secured?" ) ); if( one_in( 2 ) ) { //And another 50%, intended cumulative mod_fatigue( nutr ); } } if( ( nutr > 0 && get_hunger() < -400 ) || ( comest.quench > 0 && get_thirst() < -400 ) ) { add_msg_if_player( _( "Mmm. You can still fit some more in...but maybe you should get comfortable and sleep." ) ); if( !one_in( 3 ) ) { //Third check, this one at 66% mod_fatigue( nutr ); } } if( ( nutr > 0 && get_hunger() < -600 ) || ( comest.quench > 0 && get_thirst() < -600 ) ) { add_msg_if_player( _( "That filled a hole! Time for bed..." ) ); // At this point, you're done. Schlaf gut. mod_fatigue( nutr ); } } // Moved here and changed a bit - it was too complex // Incredibly minor stuff like this shouldn't require complexity if( !is_npc() && has_trait( trait_id( "SLIMESPAWNER" ) ) && ( get_hunger() < capacity + 40 || get_thirst() < capacity + 40 ) ) { add_msg_if_player( m_mixed, _( "You feel as though you're going to split open! In a good way?" ) ); mod_pain( 5 ); std::vector<tripoint> valid; for( const tripoint &dest : g->m.points_in_radius( pos(), 1 ) ) { if( g->is_empty( dest ) ) { valid.push_back( dest ); } } int numslime = 1; for( int i = 0; i < numslime && !valid.empty(); i++ ) { const tripoint target = random_entry_removed( valid ); if( monster *const slime = g->summon_mon( mon_player_blob, target ) ) { slime->friendly = -1; } } mod_hunger( 40 ); mod_thirst( 40 ); //~slimespawns have *small voices* which may be the Nice equivalent //~of the Rat King's ALL CAPS invective. Probably shared-brain telepathy. add_msg_if_player( m_good, _( "hey, you look like me! let's work together!" ) ); } // Last thing that happens before capping hunger if( get_hunger() < capacity && has_trait( trait_id( "EATHEALTH" ) ) ) { int excess_food = capacity - get_hunger(); add_msg_player_or_npc( _( "You feel the %s filling you out." ), _( "<npcname> looks better after eating the %s." ), food.tname().c_str() ); // Guaranteed 1 HP healing, no matter what. You're welcome. ;-) if( excess_food <= 5 ) { healall( 1 ); } else { // Straight conversion, except it's divided amongst all your body parts. healall( excess_food /= 5 ); } // Note: We want this here to prevent "you can't finish this" messages set_hunger( capacity ); } cap_nutrition_thirst( *this, capacity, nutr > 0, comest.quench > 0 ); }
bool ImageInput::read_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *data, stride_t xstride, stride_t ystride, stride_t zstride) { if (! m_spec.valid_tile_range (xbegin, xend, ybegin, yend, zbegin, zend)) return false; chend = clamp (chend, chbegin+1, m_spec.nchannels); int nchans = chend - chbegin; // native_pixel_bytes is the size of a pixel in the FILE, including // the per-channel format. stride_t native_pixel_bytes = (stride_t) m_spec.pixel_bytes (chbegin, chend, true); // perchanfile is true if the file has different per-channel formats bool perchanfile = m_spec.channelformats.size(); // native_data is true if the user asking for data in the native format bool native_data = (format == TypeDesc::UNKNOWN || (format == m_spec.format && !perchanfile)); if (format == TypeDesc::UNKNOWN && xstride == AutoStride) xstride = native_pixel_bytes; m_spec.auto_stride (xstride, ystride, zstride, format, nchans, xend-xbegin, yend-ybegin); // Do the strides indicate that the data area is contiguous? bool contiguous = (native_data && xstride == native_pixel_bytes) || (!native_data && xstride == (stride_t)m_spec.pixel_bytes(false)); contiguous &= (ystride == xstride*(xend-xbegin) && (zstride == ystride*(yend-ybegin) || (zend-zbegin) <= 1)); int nxtiles = (xend - xbegin + m_spec.tile_width - 1) / m_spec.tile_width; int nytiles = (yend - ybegin + m_spec.tile_height - 1) / m_spec.tile_height; int nztiles = (zend - zbegin + m_spec.tile_depth - 1) / m_spec.tile_depth; // If user's format and strides are set up to accept the native data // layout, and we're asking for a whole number of tiles (no partial // tiles at the edges), then read the tile directly into the user's // buffer. if (native_data && contiguous && (xend-xbegin) == nxtiles*m_spec.tile_width && (yend-ybegin) == nytiles*m_spec.tile_height && (zend-zbegin) == nztiles*m_spec.tile_depth) { if (chbegin == 0 && chend == m_spec.nchannels) return read_native_tiles (xbegin, xend, ybegin, yend, zbegin, zend, data); // Simple case else return read_native_tiles (xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend, data); } // No such luck. Just punt and read tiles individually. bool ok = true; stride_t pixelsize = native_data ? native_pixel_bytes : (format.size() * nchans); stride_t full_pixelsize = native_data ? m_spec.pixel_bytes(true) : (format.size() * m_spec.nchannels); stride_t full_tilewidthbytes = full_pixelsize * m_spec.tile_width; stride_t full_tilewhbytes = full_tilewidthbytes * m_spec.tile_height; stride_t full_tilebytes = full_tilewhbytes * m_spec.tile_depth; size_t prefix_bytes = m_spec.pixel_bytes (0,chbegin,true); std::vector<char> buf; for (int z = zbegin; z < zend; z += std::max(1,m_spec.tile_depth)) { int zd = std::min (zend-z, m_spec.tile_depth); for (int y = ybegin; y < yend; y += m_spec.tile_height) { char *tilestart = ((char *)data + (z-zbegin)*zstride + (y-ybegin)*ystride); int yh = std::min (yend-y, m_spec.tile_height); for (int x = xbegin; ok && x < xend; x += m_spec.tile_width) { int xw = std::min (xend-x, m_spec.tile_width); // Full tiles are read directly into the user buffer, // but partial tiles (such as at the image edge) or // partial channel subsets are read into a buffer and // then copied. if (xw == m_spec.tile_width && yh == m_spec.tile_height && zd == m_spec.tile_depth && !perchanfile && chbegin == 0 && chend == m_spec.nchannels) { // Full tile, either native data or not needing // per-tile data format conversion. ok &= read_tile (x, y, z, format, tilestart, xstride, ystride, zstride); } else { buf.resize (full_tilebytes); ok &= read_tile (x, y, z, perchanfile ? TypeDesc::UNKNOWN : format, &buf[0], full_pixelsize, full_tilewidthbytes, full_tilewhbytes); if (ok) copy_image (nchans, xw, yh, zd, &buf[prefix_bytes], pixelsize, full_pixelsize, full_tilewidthbytes, full_tilewhbytes, tilestart, xstride, ystride, zstride); // N.B. It looks like read_tiles doesn't handle the // per-channel data types case fully, but it does! // The call to read_tile() above handles the case of // per-channel data types, converting to to desired // format, so all we have to do on our own is the // copy_image. } tilestart += m_spec.tile_width * xstride; } if (! ok) break; } } if (! ok) error ("ImageInput::read_tiles : no support for format %s", m_spec.format.c_str()); return ok; }
bool ImageInput::read_scanlines (int ybegin, int yend, int z, int chbegin, int chend, TypeDesc format, void *data, stride_t xstride, stride_t ystride) { chend = clamp (chend, chbegin+1, m_spec.nchannels); int nchans = chend - chbegin; yend = std::min (yend, spec().y+spec().height); size_t native_pixel_bytes = m_spec.pixel_bytes (chbegin, chend, true); imagesize_t native_scanline_bytes = clamped_mult64 ((imagesize_t)m_spec.width, (imagesize_t)native_pixel_bytes); bool native = (format == TypeDesc::UNKNOWN); size_t pixel_bytes = native ? native_pixel_bytes : format.size()*nchans; if (native && xstride == AutoStride) xstride = pixel_bytes; stride_t zstride = AutoStride; m_spec.auto_stride (xstride, ystride, zstride, format, nchans, m_spec.width, m_spec.height); bool contiguous = (xstride == (stride_t) native_pixel_bytes && ystride == (stride_t) native_scanline_bytes); // If user's format and strides are set up to accept the native data // layout, read the scanlines directly into the user's buffer. bool rightformat = (format == TypeDesc::UNKNOWN) || (format == m_spec.format && m_spec.channelformats.empty()); if (rightformat && contiguous) { if (chbegin == 0 && chend == m_spec.nchannels) return read_native_scanlines (ybegin, yend, z, data); else return read_native_scanlines (ybegin, yend, z, chbegin, chend, data); } // No such luck. Read scanlines in chunks. const imagesize_t limit = 16*1024*1024; // Allocate 16 MB, or 1 scanline int chunk = std::max (1, int(limit / native_scanline_bytes)); boost::scoped_array<char> buf (new char [chunk * native_scanline_bytes]); bool ok = true; int scanline_values = m_spec.width * nchans; for (; ok && ybegin < yend; ybegin += chunk) { int y1 = std::min (ybegin+chunk, yend); ok &= read_native_scanlines (ybegin, y1, z, chbegin, chend, &buf[0]); if (! ok) break; int nscanlines = y1 - ybegin; int chunkvalues = scanline_values * nscanlines; if (m_spec.channelformats.empty()) { // No per-channel formats -- do the conversion in one shot if (contiguous) { ok = convert_types (m_spec.format, &buf[0], format, data, chunkvalues); } else { ok = parallel_convert_image (nchans, m_spec.width, nscanlines, 1, &buf[0], m_spec.format, AutoStride, AutoStride, AutoStride, data, format, xstride, ystride, zstride); } } else { // Per-channel formats -- have to convert/copy channels individually size_t offset = 0; for (int c = 0; ok && c < nchans; ++c) { TypeDesc chanformat = m_spec.channelformats[c+chbegin]; ok = convert_image (1 /* channels */, m_spec.width, nscanlines, 1, &buf[offset], chanformat, native_pixel_bytes, AutoStride, AutoStride, (char *)data + c*format.size(), format, xstride, ystride, zstride); offset += chanformat.size (); } } if (! ok) error ("ImageInput::read_scanlines : no support for format %s", m_spec.format.c_str()); data = (char *)data + ystride*nscanlines; } return ok; }
static void ReadReverbDef (int lump) { FScanner sc; const ReverbContainer *def; ReverbContainer *newenv; REVERB_PROPERTIES props; char *name; int id1, id2, i, j; bool inited[NUM_REVERB_FIELDS]; BYTE bools[32]; sc.OpenLumpNum(lump); while (sc.GetString ()) { name = copystring (sc.String); sc.MustGetNumber (); id1 = sc.Number; sc.MustGetNumber (); id2 = sc.Number; sc.MustGetStringName ("{"); memset (inited, 0, sizeof(inited)); props.Instance = 0; props.Flags = 0; while (sc.MustGetString (), NUM_REVERB_FIELDS > (i = sc.MustMatchString (ReverbFieldNames))) { if (ReverbFields[i].Float) { sc.MustGetFloat (); props.*ReverbFields[i].Float = (float)clamp (sc.Float, double(ReverbFields[i].Min)/1000, double(ReverbFields[i].Max)/1000); } else if (ReverbFields[i].Int) { sc.MustGetNumber (); props.*ReverbFields[i].Int = (j = clamp (sc.Number, ReverbFields[i].Min, ReverbFields[i].Max)); if (i == 0 && j != sc.Number) { sc.ScriptError ("The Environment field is out of range."); } } else { sc.MustGetString (); bools[ReverbFields[i].Flag] = sc.MustMatchString (BoolNames); } inited[i] = true; } if (!inited[0]) { sc.ScriptError ("Sound %s is missing an Environment field.", name); } // Add the new environment to the list, filling in uninitialized fields // with values from the standard environment specified. def = DefaultEnvironments[props.Environment]; for (i = 0; i < NUM_REVERB_FIELDS; ++i) { if (ReverbFields[i].Float) { if (!inited[i]) { props.*ReverbFields[i].Float = def->Properties.*ReverbFields[i].Float; } } else if (ReverbFields[i].Int) { if (!inited[i]) { props.*ReverbFields[i].Int = def->Properties.*ReverbFields[i].Int; } } else { if (!inited[i]) { int mask = 1 << ReverbFields[i].Flag; if (def->Properties.Flags & mask) { props.Flags |= mask; } } else { if (bools[ReverbFields[i].Flag]) { props.Flags |= 1 << ReverbFields[i].Flag; } } } } newenv = new ReverbContainer; newenv->Next = NULL; newenv->Name = name; newenv->ID = (id1 << 8) | id2; newenv->Builtin = false; newenv->Properties = props; newenv->SoftwareWater = false; S_AddEnvironment (newenv); } }
int compare_llhh(const void *a, const void *b) { return (int)clamp(((float *)a)[0]*N, 0, N-1) - (int)clamp(((float *)b)[0]*N, 0, N-1); }
// *************************************************************************** void CQuadGridClipClusterQTreeNode::clip(CClipTrav *clipTrav) { // if empty (test important for branch and leave clusters) if(Empty) return; H_BEFORE( NL3D_QuadClip_NodeClip ); // Then clip against pyramid bool unspecified= false; bool visible= true; for(sint i=0;i<(sint)clipTrav->WorldPyramid.size();i++) { // We are sure that pyramid has normalized plane normals. if(!BBoxExt.clipBack(clipTrav->WorldPyramid[i])) { visible= false; break; } // else test is the bbox is partially or fully in the plane else if(!unspecified) { // if clipFront AND clipBack, it means partially. if(BBoxExt.clipFront(clipTrav->WorldPyramid[i])) unspecified= true; } } H_AFTER( NL3D_QuadClip_NodeClip ); // if visible, parse sons if(visible) { // clip sons or cluster sons if(unspecified) { if( LeafNode) { // clip DistMax. CVector c= BBoxExt.getCenter(); float dist= (c - clipTrav->CamPos).norm(); dist-= BBoxExt.getRadius(); sint minDistSetup= (sint)floor(Owner->_NumDist*dist/Owner->_DistMax); // NB if too far, set _NumDist (ie will clip only the infinite objects ones) clamp(minDistSetup, 0, (sint)Owner->_NumDist); // clip the sons individually H_AUTO( NL3D_QuadClip_SonsClip ); ListNode.clipSons(minDistSetup); } else { // clip cluster sons Sons[0]->clip(clipTrav); Sons[1]->clip(clipTrav); Sons[2]->clip(clipTrav); Sons[3]->clip(clipTrav); } } else { // udpdate the sons, but don't clip, because we know they are fully visible. clipTrav->ForceNoFrustumClip= true; // show all cluster sons or sons noFrustumClip(clipTrav); // reset flag clipTrav->ForceNoFrustumClip= false; } } }
int main(int argc, char *arg[]) { if(argc < 2) { fprintf(stderr, "usage: %s input.pfm [-c a1 b1]\n", arg[0]); exit(1); } int wd, ht; float *input = read_pfm(arg[1], &wd, &ht); float max = 0.0f; // sanity checks: // for(int k=0;k<3*wd*ht;k++) input[k] = clamp(input[k], 0.0f, 1.0f); // correction requested? if(argc >= 9 && !strcmp(arg[2], "-c")) { const float a[3] = {atof(arg[3]), atof(arg[4]), atof(arg[5])}, b[3] = {atof(arg[6]), atof(arg[7]), atof(arg[8])}; // const float m[3] = {1, 1, 1}; // 2.0f*sqrt(a[0]*1.0f+b[0])/a[0], // 2.0f*sqrt(a[1]*1.0f+b[1])/a[1], // 2.0f*sqrt(a[2]*1.0f+b[2])/a[2]}; #if 1 // dump curves: for(int k=0;k<N;k++) { for(int c=0;c<3;c++) { // const float y = k/(N-1.0f); // const float x = m[c]*m[c]*a[c]*y*y/4.0f - b[c]/a[c]; float x = k/(N-1.0f)/a[c]; const float d = fmaxf(0.0f, x + 3./8. + (b[c]/a[c])*(b[c]/a[c])); x = 2.0f*sqrtf(d); fprintf(stderr, "%f ", x); } fprintf(stderr, "\n"); } #endif for(int k=0;k<wd*ht;k++) { for(int c=0;c<3;c++) { // input[3*k+c] = 2.0f*sqrtf(a[c]*input[3*k+c]+b[c])/(a[c]*m[c]); input[3*k+c] = input[3*k+c] / a[c]; const float d = fmaxf(0.0f, input[3*k+c] + 3./8. + (b[c]/a[c])*(b[c]/a[c])); input[3*k+c] = 2.0f*sqrtf(d); max = fmaxf(max, input[3*k+c]); } } for(int k=0;k<3*wd*ht;k++) input[k] /= max; } else if(argc >= 4 && !strcmp(arg[2], "-h")) { int bins = 0; float *hist = read_histogram(arg[3], &bins); float *inv_hist = (float *)malloc(3*sizeof(float)*bins); invert_histogram(hist, inv_hist, bins); #if 1 // output curves and their inverse: for(int k=0;k<bins;k++) // fprintf(stderr, "%f %f %f %f %f %f %f\n", k/(float)bins, hist[3*k], hist[3*k+1], hist[3*k+2], inv_hist[3*k], inv_hist[3*k+1], inv_hist[3*k+2]); fprintf(stderr, "%f %f %f\n", inv_hist[3*k], inv_hist[3*k+1], inv_hist[3*k+2]); // fprintf(stderr,"scanned %d bins\n", bins); #endif for(int k=0;k<wd*ht;k++) { for(int c=0;c<3;c++) { float f = clamp(input[3*k+c]*bins, 0, bins-2); const int bin = (int)f; f -= bin; input[3*k+c] = (1.0f-f)*inv_hist[3*bin+c] + f*inv_hist[3*(bin+1)+c]; } } } float std[N][3] = {{0.0f}}; float cnt[N][3] = {{0.0f}}; // one level haar decomposition, separable, decimated, lifting scheme for(int j=0;j<ht;j++) { for(int i=0;i<wd-1;i+=2) { float *buf = input + 3*(wd*j + i); for(int c=0;c<3;c++) { buf[c] += buf[3+c]; buf[c] *= .5f; buf[3+c] -= buf[c]; } // buf += 3; } } for(int i=0;i<wd;i++) { for(int j=0;j<ht-1;j+=2) { float *buf = input + 3*(wd*j + i); for(int c=0;c<3;c++) { buf[c] += buf[3*wd+c]; buf[c] *= .5f; buf[3*wd+c] -= buf[c]; } // buf += 3*wd; } } #if 0 // debug: write full wavelet transform: write_pfm("wt.pfm", input, wd, ht); // debug: write LL float *out = (float *)malloc(sizeof(float)*3*wd/2*ht/2); for(int j=0;j<ht-1;j+=2) { for(int i=0;i<wd-1;i+=2) { for(int c=0;c<3;c++) { out[3*((wd/2)*(j/2)+(i/2))+c] = input[3*(wd*j+i)+c]; } } } write_pfm("LL.pfm", out, wd/2, ht/2); free(out); #endif // sort pairs (LL,HH) for each color channel: float *llhh = (float *)malloc(sizeof(float)*wd*ht/2); for(int c=0;c<3;c++) { int k = 0; for(int j=0;j<ht-1;j+=2) { for(int i=0;i<wd-1;i+=2) { llhh[2*k] = input[3*(wd*j+i)+c]; llhh[2*k+1] = fabsf(input[3*(wd*(j+1)+(i+1))+c]); k++; } } qsort(llhh, k, 2*sizeof(float), compare_llhh); // estimate std deviation for every bin we've got: for(int begin=0;begin<k;) { // LL is used to estimate brightness: const int bin = (int)clamp(llhh[2*begin]*N, 0, N-1); int end = begin+1; while((end < k) && ((int)clamp(llhh[2*end]*N, 0, N-1) == bin)) end++; assert(end >= k || bin <= (int)clamp(llhh[2*end]*N, 0, N-1)); // fprintf(stderr, "from %d (%d) -- %d (%d)\n", begin, bin, end, (int)clamp(llhh[2*end]*N, 0, N-1)); // estimate noise by robust statistic (assumes zero mean of HH band): // MAD: median(|Y - med(Y)|) = 0.6745 sigma // if(end - begin > 10) // fprintf(stdout, "%d %f %d\n", bin, median(llhh+2*begin, end-begin)/0.6745, end - begin); std[bin][c] += median(llhh+2*begin, end-begin)/0.6745; cnt[bin][c] = end - begin; begin = end; } } #if 0 // recover noise curve: for(int k=0;k<wd*ht;k++) { for(int c=0;c<3;c++) { const int i = clamp(ref[3*k+c]*N, 0, N-1); cnt[i][c] ++; const float diff = input[3*k+c] - ref[3*k+c]; // assume zero mean: var[i][c] += diff*diff; // - E(X^2) } } #endif #if 0 // normalize for(int i=0;i<N;i++) for(int c=0;c<3;c++) if(cnt[i][c] > 0.0f) std[i][c] /= cnt[i][c]; else std[i][c] = 0.0f; #endif // scale back in case we needed to bin it down: if(max > 0.0f) for(int i=0;i<N;i++) for(int k=0;k<3;k++) std[i][k] *= max; // output variance per brightness level: // fprintf(stdout, "# bin std_r std_g std_b hist_r hist_g hist_b cdf_r cdf_g cdf_b\n"); float sum[3] = {0.0f}; for(int i=0;i<N;i++) for(int k=0;k<3;k++) sum[k] += std[i][k]; float cdf[3] = {0.0f}; for(int i=0;i<N;i++) { fprintf(stdout, "%f %f %f %f %f %f %f %f %f %f\n", i/(float)N, std[i][0], std[i][1], std[i][2], cnt[i][0], cnt[i][1], cnt[i][2], cdf[0]/sum[0], cdf[1]/sum[1], cdf[2]/sum[2]); // cdf[0], cdf[1], cdf[2]); for(int k=0;k<3;k++) cdf[k] += std[i][k]; } free(llhh); free(input); exit(0); }
void AI_Car_Experimental::updateSteer() { #ifdef VISUALIZE_AI_DEBUG steerlook.clear(); #endif const BEZIER *curr_patch_ptr = GetCurrentPatch(car); //if car has no contact with track, just let it roll if (!curr_patch_ptr || isRecovering) { last_patch = getNearestPatch(last_patch); //if car is off track, steer the car towards the last patch it was on //this should get the car back on track curr_patch_ptr = last_patch; //recover to the road. if(recover(curr_patch_ptr)){ return; } } last_patch = curr_patch_ptr; //store the last patch car was on BEZIER curr_patch = RevisePatch(curr_patch_ptr, use_racingline); #ifdef VISUALIZE_AI_DEBUG steerlook.push_back(curr_patch); #endif //if there is no next patch (probably a non-closed track), let it roll if (!curr_patch.GetNextPatch()) return; BEZIER next_patch = RevisePatch(curr_patch.GetNextPatch(), use_racingline); //find the point to steer towards float track_width = GetPatchWidthVector(curr_patch).Magnitude(); float lookahead = track_width * LOOKAHEAD_FACTOR1 + car->GetVelocity().Magnitude() * LOOKAHEAD_FACTOR2; lookahead = 1.0; float length = 0.0; MATHVECTOR <float, 3> dest_point = GetPatchFrontCenter(next_patch); while (length < lookahead) { #ifdef VISUALIZE_AI_DEBUG steerlook.push_back(next_patch); #endif length += GetPatchDirection(next_patch).Magnitude(); dest_point = GetPatchFrontCenter(next_patch); //if there is no next patch for whatever reason, stop lookahead if (!next_patch.GetNextPatch()) { length = lookahead; break; } next_patch = RevisePatch(next_patch.GetNextPatch(), use_racingline); //if next patch is a very sharp corner, stop lookahead if (GetPatchRadius(next_patch) < LOOKAHEAD_MIN_RADIUS) { length = lookahead; break; } } MATHVECTOR <float, 3> next_position = TransformToWorldspace(dest_point); MATHVECTOR <float, 3> car_position = car->GetCenterOfMassPosition(); MATHVECTOR <float, 3> car_orientation = direction::Forward; (car->GetOrientation()).RotateVector(car_orientation); MATHVECTOR <float, 3> desire_orientation = next_position - car_position; //car's direction on the horizontal plane car_orientation[2] = 0; //desired direction on the horizontal plane desire_orientation[2] = 0; car_orientation = car_orientation.Normalize(); desire_orientation = desire_orientation.Normalize(); //the angle between car's direction and unit y vector (forward direction) double alpha = Angle(car_orientation[0], car_orientation[1]); //the angle between desired direction and unit y vector (forward direction) double beta = Angle(desire_orientation[0], desire_orientation[1]); //calculate steering angle and direction double angle = beta - alpha; //angle += steerAwayFromOthers(c, dt, othercars, angle); //sum in traffic avoidance bias if (angle > -360.0 && angle <= -180.0) angle = -(360.0 + angle); else if (angle > -180.0 && angle <= 0.0) angle = - angle; else if (angle > 0.0 && angle <= 180.0) angle = - angle; else if (angle > 180.0 && angle <= 360.0) angle = 360.0 - angle; float optimum_range = car->GetOptimumSteeringAngle(); angle = clamp(angle, -optimum_range, optimum_range); float steer_value = angle / car->GetMaxSteeringAngle(); if (steer_value > 1.0) steer_value = 1.0; else if (steer_value < -1.0) steer_value = -1.0; assert(!isnan(steer_value)); if(isRecovering){ // If we are driving backwards, we need to invert steer direction. steer_value = steer_value > 0.0 ? -1.0 : 1.0; } inputs[CARINPUT::STEER_RIGHT] = steer_value; }
CMaterialManager::CMaterialManager() { qualityLevel = 5.0; CFG_GET_VAL("materialmgr.quality", Float, qualityLevel); qualityLevel = clamp(qualityLevel, 0.0f, 10.0f); }
void AI_Car_Experimental::analyzeOthers(float dt, const std::list <CAR> & checkcars) { //const float speed = std::max(1.0f,car->GetVelocity().Magnitude()); const float half_carlength = 1.25; //in meters //std::cout << speed << ": " << authority << std::endl; //const MATHVECTOR <float, 3> steer_right_axis = direction::Right; const MATHVECTOR <float, 3> throttle_axis = direction::Forward; #ifdef VISUALIZE_AI_DEBUG //avoidancedraw->ClearLine(); #endif for (std::list <CAR>::const_iterator i = checkcars.begin(); i != checkcars.end(); ++i) { if (&(*i) != car) { struct AI_Car_Experimental::OTHERCARINFO & info = othercars[&(*i)]; //find direction of other cars in our frame MATHVECTOR <float, 3> relative_position = i->GetCenterOfMassPosition() - car->GetCenterOfMassPosition(); (-car->GetOrientation()).RotateVector(relative_position); //std::cout << relative_position.dot(throttle_axis) << ", " << relative_position.dot(steer_right_axis) << std::endl; //only make a move if the other car is within our distance limit float fore_position = relative_position.dot(throttle_axis); //float speed_diff = i->GetVelocity().dot(throttle_axis) - car->GetVelocity().dot(throttle_axis); //positive if other car is faster MATHVECTOR <float, 3> myvel = car->GetVelocity(); MATHVECTOR <float, 3> othervel = i->GetVelocity(); (-car->GetOrientation()).RotateVector(myvel); (-i->GetOrientation()).RotateVector(othervel); float speed_diff = othervel.dot(throttle_axis) - myvel.dot(throttle_axis); //positive if other car is faster //std::cout << speed_diff << std::endl; //float distancelimit = clamp(distancelimitcoeff*-speed_diff, distancelimitmin, distancelimitmax); const float fore_position_offset = -half_carlength; if (fore_position > fore_position_offset)// && fore_position < distancelimit) //only pay attention to cars roughly in front of us { //float horizontal_distance = relative_position.dot(steer_right_axis); //fallback method if not on a patch //float orig_horiz = horizontal_distance; const BEZIER * othercarpatch = GetCurrentPatch(&(*i)); const BEZIER * mycarpatch = GetCurrentPatch(car); if (othercarpatch && mycarpatch) { float my_track_placement = GetHorizontalDistanceAlongPatch(*mycarpatch, TransformToPatchspace(car->GetCenterOfMassPosition())); float their_track_placement = GetHorizontalDistanceAlongPatch(*othercarpatch, TransformToPatchspace(i->GetCenterOfMassPosition())); float speed_diff_denom = clamp(speed_diff, -100, -0.01); float eta = (fore_position-fore_position_offset)/-speed_diff_denom; info.fore_distance = fore_position; if (!info.active) info.eta = eta; else info.eta = RateLimit(info.eta, eta, 10.f*dt, 10000.f*dt); float horizontal_distance = their_track_placement - my_track_placement; //if (!info.active) info.horizontal_distance = horizontal_distance; /*else info.horizontal_distance = RateLimit(info.horizontal_distance, horizontal_distance, spacingdistance*dt, spacingdistance*dt);*/ //std::cout << info.horizontal_distance << ", " << info.eta << std::endl; info.active = true; } else info.active = false; //std::cout << orig_horiz << ", " << horizontal_distance << ", " << fore_position << ", " << speed_diff << std::endl; /*if (!min_horizontal_distance) min_horizontal_distance = optional <float> (horizontal_distance); else if (std::abs(min_horizontal_distance.get()) > std::abs(horizontal_distance)) min_horizontal_distance = optional <float> (horizontal_distance);*/ } else info.active = false; /*#ifdef VISUALIZE_AI_DEBUG if (info.active) { avoidancedraw->AddLinePoint(car->GetCenterOfMassPosition()); MATHVECTOR <float, 3> feeler1(speed*info.eta,0,0); car->GetOrientation().RotateVector(feeler1); MATHVECTOR <float, 3> feeler2(0,-info.horizontal_distance,0); car->GetOrientation().RotateVector(feeler2); avoidancedraw->AddLinePoint(car->GetCenterOfMassPosition()+feeler1+feeler2); avoidancedraw->AddLinePoint(car->GetCenterOfMassPosition()); } #endif*/ } } }
int main(int argc, char *argv[]) try { physics_driftmax = 0.0025f; GLWin glwin("point cloud push interaction"); RSCam dcam; dcam.Init((argc == 2) ? argv[1] : NULL); Image<unsigned short> dimage(dcam.dcamera()); glwin.ViewAngle = dcam.fov().y; float viewdist = 2.0f; float yaw = 120; int mousexold = 0; Mesh mesh; bool pause = false; bool debuglines=false; int center = 0; bool chains = true; bool usehull = false; std::vector<RigidBody*> rigidbodies; std::vector < std::pair<RigidBody*, RigidBody*>> links; for (float x = -0.2f; x < 0.2f; x+= 0.07f) for(float z: {0.350f}) for (float y = -0.2f; y <= 0.2f; y += 0.07f) { rigidbodies.push_back(new RigidBody({ AsShape(WingMeshDual(WingMeshCube(0.025f),0.028f)) }, { x,y,z })); //rigidbodies.push_back(new RigidBody({ AsShape(WingMeshCube(0.025f) ) }, { x,y,z })); links.push_back({(y > -0.2f)?rigidbodies[rigidbodies.size() - 2]:NULL , rigidbodies.back()}); } //rigidbodies.push_back(new RigidBody({ AsShape(WingMeshCube(0.05f)) }, { 0,0,0.50f })); auto seesaw = new RigidBody({ AsShape(WingMeshBox({ 0.20f, 0.015f, 0.05f })) }, { 0,0,0.45f }); rigidbodies.push_back(seesaw); glwin.keyboardfunc = [&](unsigned char key, int x, int y)->void { switch (std::tolower(key)) { case 'q': case 27: exit(0); break; // 27 is ESC case ' ': pause = !pause; break; case 'c': chains = !chains; break; case 'd': debuglines = !debuglines; break; case 'h': usehull = !usehull; break; case 'r': for (auto &rb : rigidbodies) { rb->angular_momentum = rb->linear_momentum = float3(0.0f);rb->pose() = { rb->position_start,rb->orientation_start }; } break; default: std::cout << "unassigned key (" << (int)key << "): '" << key << "'\n"; break; } }; if (dcam.dev->supports_option(rs::option::r200_lr_auto_exposure_enabled)) dcam.dev->set_option(rs::option::r200_lr_auto_exposure_enabled, 1); while (glwin.WindowUp()) { if (glwin.MouseState) { yaw += glwin.mousepos.x - mousexold; } mousexold = glwin.mousepos.x; viewdist *= powf(1.1f, (float)glwin.mousewheel); if (!pause) dimage = dcam.GetDepth(); glPushAttrib(GL_ALL_ATTRIB_BITS); glViewport(0, 0, glwin.res.x, glwin.res.y); glClearColor(0.1f, 0.1f, 0.15f, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPerspective(glwin.ViewAngle, (double)glwin.aspect_ratio(), 0.01f, 50.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); gluLookAt(0, 0, viewdist, 0, 0, 0, 0, -1, 0); glEnable(GL_DEPTH_TEST); glTranslatef(0, 0, 0.35f); glRotatef(yaw, 0, 1, 0); glTranslatef(0, 0, -0.35f); std::vector<float3> pts; std::vector<float3> outliers; std::vector<float3> vpts; glDisable(GL_BLEND); float2 wrange = { 0.20f,0.60f }; auto dp_image_c = Transform(dimage, [](unsigned short s) {return byte3((unsigned char)clamp(255 - s / 4, 0, 255)); }); drawimage(dp_image_c, { 0.78f,0.22f }, { 0.2f,-0.2f }, 3); float depth_scale = (dcam.dev) ? dcam.dev->get_depth_scale() : 0.001f; // to put into meters // if file assume file is mm for (auto p : rect_iteration(dimage.dim())) // p is int2 from 0,0 to w,h of dcam { float d = dimage.pixel(p) * depth_scale; // d is in meters, whereas depth[i] is in camera units mm for R200, .125mm for SR300 ivycam if (p.x<5 || p.x> dimage.dim().x - 5 || p.y<5 || p.y>dimage.dim().y - 5) continue; // crop, seems to be lots of noise at the edges if (d > 1.0f) // just too far continue; float3 v = dimage.cam.deprojectz(asfloat2(p), d); if (d>wrange.x && d < wrange.y) pts.push_back(v); else outliers.push_back(v); } vpts = ObtainVoxelPointCloud(pts, 0.0082f, 8); std::vector<std::pair<float3, float3>> lines; std::vector<std::pair<float3, float3>> glines; if (1)// && pts.size()) { std::vector<LimitLinear> linears; std::vector<LimitAngular> angulars; physics_gravity = { 0, (float) chains,0 }; // ugg y is down if(!usehull) for(auto rb:rigidbodies) { if (!rb->shapes[0].planes.size()) rb->shapes[0].planes = Planes(rb->shapes[0].verts, rb->shapes[0].tris); auto planes = Transform(rb->shapes[0].planes, [&](float4 p) { return rb->pose().TransformPlane(p);}); rb->gravscale = (float)chains; float separation = FLT_MAX; float3 pushpoint = float3(0, 0, 0); // float4 pushplane; for (auto p : vpts) { auto plane = mostabove(planes, p); float sep; if ((sep = dot(plane, float4(p, 1))) < separation) { pushpoint = p; pushplane = plane; separation = sep; } } if (separation > 0.1f) continue; float3 closestpoint = ProjectOntoPlane(pushplane, pushpoint); pushplane = float4({ -pushplane.xyz(), -dot(-pushplane.xyz(),pushpoint) }); linears.push_back(ConstrainAlongDirection(NULL, pushpoint, rb, rb->pose().inverse()*closestpoint, pushplane.xyz(), 0, 100.0f)); // FLT_MAX)); lines.push_back({ closestpoint,pushpoint }); auto cp=Separated(rb->shapes[0].verts, rb->position, rb->orientation, { pushpoint }, { 0,0,0 }, { 0,0,0,1 }, 1); glines.push_back({ cp.p0w, cp.p1w }); } Append(linears, ConstrainPositionNailed(NULL, seesaw->position_start, seesaw, { 0, 0, 0 })); Append(angulars, ConstrainAngularRange(NULL, seesaw, { 0, 0, 0, 1 }, { 0, 0,-20 }, { 0, 0,20 })); if (chains) for (auto link : links) Append(linears, ConstrainPositionNailed(link.first,link.first? float3(0, 0.035f, 0) : link.second->position_start-float3(0, -0.035f, 0) , link.second, { 0,-0.035f,0 })); if(!pause) if(usehull && vpts.size()>5) PhysicsUpdate(rigidbodies, linears, angulars, { &vpts }); else PhysicsUpdate(rigidbodies, linears, angulars, std::vector<std::vector<float3>*>()); } glColor3f(1, 1, 1); glwirefrustumz(dcam.deprojectextents(), { 0.1f,1.0f }); // draw the camera frustum volume glPushAttrib(GL_ALL_ATTRIB_BITS); glPointSize(1); glBegin(GL_POINTS); glColor3f(0, 1, 0.5f); for (auto p : pts) glVertex3fv(p); glColor3f(1, 0.15f, 0.15f); for (auto p : outliers) glVertex3fv(p); glEnd(); glPointSize(3); glBegin(GL_POINTS); glColor3f(1, 1, 1); for (auto p : vpts) // was: spts glVertex3fv(p); glEnd(); glPopAttrib(); if (debuglines) { glBegin(GL_LINES); glColor3f(0, 1, 1); if (0)for (auto line : lines) glVertex3fv(line.first), glVertex3fv(line.second); glColor3f(1, 1, 0); for (auto line : glines) glVertex3fv(line.first), glVertex3fv(line.second); glEnd(); } if (usehull && vpts.size() > 5) { auto tris = calchull(vpts, 0); glBegin(GL_LINES); glColor3f(1, 1, 1); for (auto t : tris) for( int i : {0,1,1,2,2,0}) glVertex3fv(vpts[t[i]]); glEnd(); } if (chains) { glBegin(GL_LINES); glColor3f(1, 0, 1); for (auto link : links) { if(link.first) glVertex3fv(link.first->pose()* float3(0, 0, 0)), glVertex3fv(link.first->pose()* float3(0, 0.035f, 0)); glVertex3fv(link.second->pose()* float3(0, 0, 0)) , glVertex3fv(link.second->pose()* float3(0, -0.035f, 0)); } glEnd(); } glPushAttrib(GL_ALL_ATTRIB_BITS); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_TEXTURE_2D); glColor3f(0.5f, 0.5f, 0.5f); for (auto &rb : rigidbodies) rbdraw(rb); glPopAttrib(); // Restore state // Restore state glPopMatrix(); //should be currently in modelview mode glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); glMatrixMode(GL_MODELVIEW); glwin.PrintString({ 0,0 }, "esc to quit."); glwin.PrintString({ 0,1 }, "[h] collision %s ",(usehull)?"hull":"points"); glwin.SwapBuffers(); } return 0; } catch (const char *c) { MessageBox(GetActiveWindow(), c, "FAIL", 0); } catch (std::exception e) { MessageBox(GetActiveWindow(), e.what(), "FAIL", 0); }
void CBeam::InputColorRedValue( inputdata_t &inputdata ) { int nNewColor = clamp( inputdata.value.Int(), 0, 255 ); SetColor( nNewColor, m_clrRender->g, m_clrRender->b ); }
void CSpectator::OnRender() { if(!m_Active) { if(m_WasActive) { if(m_SelectedSpectatorID != NO_SELECTION) Spectate(m_SelectedSpectatorID); m_WasActive = false; } return; } m_WasActive = true; m_SelectedSpectatorID = NO_SELECTION; // draw background float Width = 400*3.0f*Graphics()->ScreenAspect(); float Height = 400*3.0f; Graphics()->MapScreen(0, 0, Width, Height); Graphics()->BlendNormal(); Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0.0f, 0.0f, 0.0f, 0.3f); RenderTools()->DrawRoundRect(Width/2.0f-300.0f, Height/2.0f-300.0f, 600.0f, 600.0f, 20.0f); Graphics()->QuadsEnd(); // clamp mouse position to selector area m_SelectorMouse.x = clamp(m_SelectorMouse.x, -280.0f, 280.0f); m_SelectorMouse.y = clamp(m_SelectorMouse.y, -280.0f, 280.0f); // draw selections float FontSize = 20.0f; float StartY = -190.0f; float LineHeight = 60.0f; bool Selected = false; if(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW) { Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f); RenderTools()->DrawRoundRect(Width/2.0f-280.0f, Height/2.0f-280.0f, 270.0f, 60.0f, 20.0f); Graphics()->QuadsEnd(); } if(m_SelectorMouse.x >= -280.0f && m_SelectorMouse.x <= -10.0f && m_SelectorMouse.y >= -280.0f && m_SelectorMouse.y <= -220.0f) { m_SelectedSpectatorID = SPEC_FREEVIEW; Selected = true; } TextRender()->TextColor(1.0f, 1.0f, 1.0f, Selected?1.0f:0.5f); TextRender()->Text(0, Width/2.0f-240.0f, Height/2.0f-265.0f, FontSize, Localize("Free-View"), -1); float x = -270.0f, y = StartY; for(int i = 0, Count = 0; i < MAX_CLIENTS; ++i) { if(!m_pClient->m_Snap.m_paPlayerInfos[i] || m_pClient->m_Snap.m_paPlayerInfos[i]->m_Team == TEAM_SPECTATORS) continue; if(++Count%9 == 0) { x += 290.0f; y = StartY; } if(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == i) { Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f); RenderTools()->DrawRoundRect(Width/2.0f+x-10.0f, Height/2.0f+y-10.0f, 270.0f, 60.0f, 20.0f); Graphics()->QuadsEnd(); } Selected = false; if(m_SelectorMouse.x >= x-10.0f && m_SelectorMouse.x <= x+260.0f && m_SelectorMouse.y >= y-10.0f && m_SelectorMouse.y <= y+50.0f) { m_SelectedSpectatorID = i; Selected = true; } TextRender()->TextColor(1.0f, 1.0f, 1.0f, Selected?1.0f:0.5f); TextRender()->Text(0, Width/2.0f+x+50.0f, Height/2.0f+y+5.0f, FontSize, m_pClient->m_aClients[i].m_aName, 220.0f); CTeeRenderInfo TeeInfo = m_pClient->m_aClients[i].m_RenderInfo; RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), vec2(Width/2.0f+x+20.0f, Height/2.0f+y+20.0f)); y += LineHeight; } TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); // draw cursor Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_Id); Graphics()->QuadsBegin(); Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f); IGraphics::CQuadItem QuadItem(m_SelectorMouse.x+Width/2.0f, m_SelectorMouse.y+Height/2.0f, 48.0f, 48.0f); Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); }
std::vector<float> Synthesizer::generate_frame() { // shift the signal left to get space for the new signal sig = sig.shift(R); for(int i = 0; i < R; i++) { sample_idx++; if(update_params() >= 0 || finished) { finished = true; break; } fpoint in = samples[sample_idx - last_phoneme_sample_idx]; // append the signal at the end sig[L - R + i] = in; } // apply analysis window std::valarray<complex> seg = sig * window, tmp(L); fft(seg); auto env = spectral_envelope(seg); //for(auto a : env) std::cout << std::fixed << a << ","; //std::cout << "\n\n"; const fpoint expect = 2 * M_PI / Ov; // frequency between two bins const fpoint bin_freq = fpoint(Fs) / L; std::valarray<fpoint> tmp_mag(L / 2 + 1); std::valarray<fpoint> tmp_frq(L / 2 + 1); for(unsigned i = 0; i <= L / 2; i++) { // compute magnitude and phase fpoint magn = abs(seg[i]) * 2; fpoint phas = arg(seg[i]); // compute phase difference fpoint pdiff = phas - last_phase[i]; last_phase[i] = phas; // subtract expected phase difference pdiff -= i * expect; // map delta phase into +/- Pi interval pdiff -= 2 * M_PI * floor(pdiff / (2 * M_PI) + 0.5); // get deviation from bin frequency from the +/- Pi interval fpoint fdev = Ov * pdiff / (2 * M_PI); // compute the k-th partials' true frequency fpoint true_freq = i * bin_freq + fdev * bin_freq; // store magnitude and true frequency in analysis arrays tmp_mag[i] = magn; tmp_frq[i] = true_freq; } // copy buffers std::valarray<fpoint> seg_mag(L / 2 + 1); std::valarray<fpoint> seg_frq(L / 2 + 1); // pitch shifting fpoint pitch_shift = 1.5; for (unsigned i = 0; i <= L / 2; i++) { unsigned index = i * pitch_shift; if (index <= L / 2) { seg_mag[index] += tmp_mag[i];// / env[i]; seg_frq[index] = tmp_frq[i] * pitch_shift; } } // synthesis for (unsigned i = 0; i <= L / 2; i++) { // get magnitude and true frequency from synthesis arrays fpoint mag = seg_mag[i]; fpoint frq = seg_frq[i]; // subtract bin mid frequency frq -= i * bin_freq; // get bin deviation from freq deviation frq /= bin_freq; // take osamp into account frq = 2 * M_PI * frq / Ov; // add the overlap phase advance back in frq += i * expect; // accumulate delta phase to get bin phase sum_phase[i] += frq; fpoint phase = sum_phase[i]; // get real and imag part seg[i] = std::polar(mag, phase); seg[L - i - 1] = 0; } ifft(seg); ova = ova.shift(R) + seg * window; std::vector<float> out(R, 0); for(unsigned i = 0; i < R; i++) { out[i] = (float)clamp(-1, 1, ova[i].real()); } return out; }
void BVH4Intersector4Hybrid<PrimitiveIntersector4>::occluded(sseb* valid_i, BVH4* bvh, Ray4& ray) { /* load ray */ const sseb valid = *valid_i; sseb terminated = !valid; sse3f ray_org = ray.org, ray_dir = ray.dir; ssef ray_tnear = ray.tnear, ray_tfar = ray.tfar; #if defined(__FIX_RAYS__) const ssef float_range = 0.1f*FLT_MAX; ray_org = clamp(ray_org,sse3f(-float_range),sse3f(+float_range)); ray_dir = clamp(ray_dir,sse3f(-float_range),sse3f(+float_range)); ray_tnear = max(ray_tnear,FLT_MIN); ray_tfar = min(ray_tfar,float(inf)); #endif const sse3f rdir = rcp_safe(ray_dir); const sse3f org(ray_org), org_rdir = org * rdir; ray_tnear = select(valid,ray_tnear,ssef(pos_inf)); ray_tfar = select(valid,ray_tfar ,ssef(neg_inf)); const ssef inf = ssef(pos_inf); /* allocate stack and push root node */ ssef stack_near[stackSizeChunk]; NodeRef stack_node[stackSizeChunk]; stack_node[0] = BVH4::invalidNode; stack_near[0] = inf; stack_node[1] = bvh->root; stack_near[1] = ray_tnear; NodeRef* stackEnd = stack_node+stackSizeChunk; NodeRef* __restrict__ sptr_node = stack_node + 2; ssef* __restrict__ sptr_near = stack_near + 2; while (1) { /* pop next node from stack */ assert(sptr_node > stack_node); sptr_node--; sptr_near--; NodeRef curNode = *sptr_node; if (unlikely(curNode == BVH4::invalidNode)) { assert(sptr_node == stack_node); break; } /* cull node if behind closest hit point */ ssef curDist = *sptr_near; const sseb active = curDist < ray_tfar; if (unlikely(none(active))) continue; /* switch to single ray traversal */ #if !defined(__WIN32__) || defined(__X86_64__) size_t bits = movemask(active); if (unlikely(__popcnt(bits) <= SWITCH_THRESHOLD)) { for (size_t i=__bsf(bits); bits!=0; bits=__btc(bits,i), i=__bsf(bits)) { if (occluded1(bvh,curNode,i,ray,ray_org,ray_dir,rdir,ray_tnear,ray_tfar)) terminated[i] = -1; } if (all(terminated)) break; ray_tfar = select(terminated,ssef(neg_inf),ray_tfar); continue; } #endif while (1) { /* test if this is a leaf node */ if (unlikely(curNode.isLeaf())) break; const sseb valid_node = ray_tfar > curDist; STAT3(shadow.trav_nodes,1,popcnt(valid_node),4); const Node* __restrict__ const node = curNode.node(); /* pop of next node */ assert(sptr_node > stack_node); sptr_node--; sptr_near--; curNode = *sptr_node; curDist = *sptr_near; #pragma unroll(4) for (unsigned i=0; i<4; i++) { const NodeRef child = node->children[i]; if (unlikely(child == BVH4::emptyNode)) break; #if defined(__AVX2__) const ssef lclipMinX = msub(node->lower_x[i],rdir.x,org_rdir.x); const ssef lclipMinY = msub(node->lower_y[i],rdir.y,org_rdir.y); const ssef lclipMinZ = msub(node->lower_z[i],rdir.z,org_rdir.z); const ssef lclipMaxX = msub(node->upper_x[i],rdir.x,org_rdir.x); const ssef lclipMaxY = msub(node->upper_y[i],rdir.y,org_rdir.y); const ssef lclipMaxZ = msub(node->upper_z[i],rdir.z,org_rdir.z); #else const ssef lclipMinX = (node->lower_x[i] - org.x) * rdir.x; const ssef lclipMinY = (node->lower_y[i] - org.y) * rdir.y; const ssef lclipMinZ = (node->lower_z[i] - org.z) * rdir.z; const ssef lclipMaxX = (node->upper_x[i] - org.x) * rdir.x; const ssef lclipMaxY = (node->upper_y[i] - org.y) * rdir.y; const ssef lclipMaxZ = (node->upper_z[i] - org.z) * rdir.z; #endif #if defined(__SSE4_1__) const ssef lnearP = maxi(maxi(mini(lclipMinX, lclipMaxX), mini(lclipMinY, lclipMaxY)), mini(lclipMinZ, lclipMaxZ)); const ssef lfarP = mini(mini(maxi(lclipMinX, lclipMaxX), maxi(lclipMinY, lclipMaxY)), maxi(lclipMinZ, lclipMaxZ)); const sseb lhit = maxi(lnearP,ray_tnear) <= mini(lfarP,ray_tfar); #else const ssef lnearP = max(max(min(lclipMinX, lclipMaxX), min(lclipMinY, lclipMaxY)), min(lclipMinZ, lclipMaxZ)); const ssef lfarP = min(min(max(lclipMinX, lclipMaxX), max(lclipMinY, lclipMaxY)), max(lclipMinZ, lclipMaxZ)); const sseb lhit = max(lnearP,ray_tnear) <= min(lfarP,ray_tfar); #endif /* if we hit the child we choose to continue with that child if it is closer than the current next child, or we push it onto the stack */ if (likely(any(lhit))) { assert(sptr_node < stackEnd); assert(child != BVH4::emptyNode); const ssef childDist = select(lhit,lnearP,inf); sptr_node++; sptr_near++; /* push cur node onto stack and continue with hit child */ if (any(childDist < curDist)) { *(sptr_node-1) = curNode; *(sptr_near-1) = curDist; curDist = childDist; curNode = child; } /* push hit child onto stack */ else { *(sptr_node-1) = child; *(sptr_near-1) = childDist; } } } } /* return if stack is empty */ if (unlikely(curNode == BVH4::invalidNode)) { assert(sptr_node == stack_node); break; } /* intersect leaf */ const sseb valid_leaf = ray_tfar > curDist; STAT3(shadow.trav_leaves,1,popcnt(valid_leaf),4); size_t items; const Primitive* prim = (Primitive*) curNode.leaf(items); terminated |= PrimitiveIntersector4::occluded(!terminated,ray,prim,items,bvh->geometry); if (all(terminated)) break; ray_tfar = select(terminated,ssef(neg_inf),ray_tfar); } store4i(valid & terminated,&ray.geomID,0); AVX_ZERO_UPPER(); }
void FFTConvolve::convolveSingle(Image im, Image filter, Image out, Convolve::BoundaryCondition b) { // Deal with the homogeneous case recursively. This is slightly // inefficient because we construct and transform the filter // twice, but it makes the code much simpler if (b == Convolve::Homogeneous) { Image result = apply(im, filter, Convolve::Zero, Multiply::Outer); Image weight(im.width, im.height, im.frames, 1); weight.set(1.0f); Image resultW = apply(weight, filter, Convolve::Zero, Multiply::Outer); out += Stats(filter).sum() * result / resultW; return; } assert(filter.width % 2 == 1 && filter.height % 2 == 1 && filter.frames % 2 == 1, "The filter must have odd dimensions\n"); int xPad = filter.width/2; int yPad = filter.height/2; int tPad = filter.frames/2; if (b == Convolve::Wrap) { xPad = yPad = tPad = 0; } Image weightT; Image imT = Image(im.width+xPad*2, im.height+yPad*2, im.frames+tPad*2, 2); //printf("1\n"); fflush(stdout); // 1) Make the padded complex image if (b == Convolve::Clamp) { for (int t = 0; t < imT.frames; t++) { int st = clamp(t-tPad, 0, im.frames-1); for (int y = 0; y < imT.height; y++) { int sy = clamp(y-yPad, 0, im.height-1); for (int x = 0; x < imT.width; x++) { int sx = clamp(x-xPad, 0, im.width-1); imT(x, y, t, 0) = im(sx, sy, st, 0); } } } } else { // Zero or Wrap imT.region(xPad, yPad, tPad, 0, im.width, im.height, im.frames, 1).set(im); } //printf("2\n"); fflush(stdout); // 2) Transform the padded image FFT::apply(imT); //printf("3\n"); fflush(stdout); // 3) Make a padded complex filter of the same size Image filterT(imT.width, imT.height, imT.frames, 2); for (int t = 0; t < filter.frames; t++) { int ft = t - filter.frames/2; if (ft < 0) ft += filterT.frames; for (int y = 0; y < filter.height; y++) { int fy = y - filter.height/2; if (fy < 0) fy += filterT.height; for (int x = 0; x < filter.width; x++) { int fx = x - filter.width/2; if (fx < 0) fx += filterT.width; filterT(fx, fy, ft, 0) = filter(x, y, t, 0); } } } //printf("4\n"); fflush(stdout); // 4) Transform the padded filter FFT::apply(filterT); //printf("5\n"); fflush(stdout); // 5) Multiply the two into a padded complex transformed result ComplexMultiply::apply(imT, filterT); //printf("6\n"); fflush(stdout); // 6) Inverse transorm the result IFFT::apply(imT); //printf("7\n"); fflush(stdout); // 7) Remove the padding, and convert back to real numbers out += imT.region(xPad, yPad, tPad, 0, im.width, im.height, im.frames, 1); }
static int clamp_thread(void *arg) { int cpunr = (unsigned long)arg; DEFINE_TIMER(wakeup_timer, noop_timer, 0, 0); static const struct sched_param param = { .sched_priority = MAX_USER_RT_PRIO/2, }; unsigned int count = 0; unsigned int target_ratio; set_bit(cpunr, cpu_clamping_mask); set_freezable(); init_timer_on_stack(&wakeup_timer); sched_setscheduler(current, SCHED_FIFO, ¶m); while (true == clamping && !kthread_should_stop() && cpu_online(cpunr)) { int sleeptime; unsigned long target_jiffies; unsigned int guard; unsigned int compensation = 0; int interval; /* jiffies to sleep for each attempt */ unsigned int duration_jiffies = msecs_to_jiffies(duration); unsigned int window_size_now; try_to_freeze(); /* * make sure user selected ratio does not take effect until * the next round. adjust target_ratio if user has changed * target such that we can converge quickly. */ target_ratio = set_target_ratio; guard = 1 + target_ratio/20; window_size_now = window_size; count++; /* * systems may have different ability to enter package level * c-states, thus we need to compensate the injected idle ratio * to achieve the actual target reported by the HW. */ compensation = get_compensation(target_ratio); interval = duration_jiffies*100/(target_ratio+compensation); /* align idle time */ target_jiffies = roundup(jiffies, interval); sleeptime = target_jiffies - jiffies; if (sleeptime <= 0) sleeptime = 1; schedule_timeout_interruptible(sleeptime); /* * only elected controlling cpu can collect stats and update * control parameters. */ if (cpunr == control_cpu && !(count%window_size_now)) { should_skip = powerclamp_adjust_controls(target_ratio, guard, window_size_now); smp_mb(); } if (should_skip) continue; target_jiffies = jiffies + duration_jiffies; mod_timer(&wakeup_timer, target_jiffies); if (unlikely(local_softirq_pending())) continue; /* * stop tick sched during idle time, interrupts are still * allowed. thus jiffies are updated properly. */ preempt_disable(); tick_nohz_idle_enter(); /* mwait until target jiffies is reached */ while (time_before(jiffies, target_jiffies)) { unsigned long ecx = 1; unsigned long eax = target_mwait; /* * REVISIT: may call enter_idle() to notify drivers who * can save power during cpu idle. same for exit_idle() */ local_touch_nmi(); stop_critical_timings(); mwait_idle_with_hints(eax, ecx); start_critical_timings(); atomic_inc(&idle_wakeup_counter); } tick_nohz_idle_exit(); preempt_enable_no_resched(); } del_timer_sync(&wakeup_timer); clear_bit(cpunr, cpu_clamping_mask); return 0; } /* * 1 HZ polling while clamping is active, useful for userspace * to monitor actual idle ratio. */ static void poll_pkg_cstate(struct work_struct *dummy); static DECLARE_DELAYED_WORK(poll_pkg_cstate_work, poll_pkg_cstate); static void poll_pkg_cstate(struct work_struct *dummy) { static u64 msr_last; static u64 tsc_last; static unsigned long jiffies_last; u64 msr_now; unsigned long jiffies_now; u64 tsc_now; u64 val64; msr_now = pkg_state_counter(); rdtscll(tsc_now); jiffies_now = jiffies; /* calculate pkg cstate vs tsc ratio */ if (!msr_last || !tsc_last) pkg_cstate_ratio_cur = 1; else { if (tsc_now - tsc_last) { val64 = 100 * (msr_now - msr_last); do_div(val64, (tsc_now - tsc_last)); pkg_cstate_ratio_cur = val64; } } /* update record */ msr_last = msr_now; jiffies_last = jiffies_now; tsc_last = tsc_now; if (true == clamping) schedule_delayed_work(&poll_pkg_cstate_work, HZ); } static int start_power_clamp(void) { unsigned long cpu; struct task_struct *thread; /* check if pkg cstate counter is completely 0, abort in this case */ if (!has_pkg_state_counter()) { pr_err("pkg cstate counter not functional, abort\n"); return -EINVAL; } set_target_ratio = clamp(set_target_ratio, 0U, MAX_TARGET_RATIO - 1); /* prevent cpu hotplug */ get_online_cpus(); /* prefer BSP */ control_cpu = 0; if (!cpu_online(control_cpu)) control_cpu = smp_processor_id(); clamping = true; schedule_delayed_work(&poll_pkg_cstate_work, 0); /* start one thread per online cpu */ for_each_online_cpu(cpu) { struct task_struct **p = per_cpu_ptr(powerclamp_thread, cpu); thread = kthread_create_on_node(clamp_thread, (void *) cpu, cpu_to_node(cpu), "kidle_inject/%ld", cpu); /* bind to cpu here */ if (likely(!IS_ERR(thread))) { kthread_bind(thread, cpu); wake_up_process(thread); *p = thread; } } put_online_cpus(); return 0; }
template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T> saturate(const detail::tvec3<T>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
int RageFileObjMem::SeekInternal( int offset ) { m_iFilePos = clamp( offset, 0, GetFileSize() ); return m_iFilePos; }