void PrecalcIOLighting(const Vec3f & pos, float radius) { g_culledStaticLightsCount = 0; for(size_t i = 0; i < g_staticLightsMax; i++) { EERIE_LIGHT * el = g_staticLights[i]; if( el && el->m_exists && el->m_ignitionStatus && !(el->extras & EXTRAS_SEMIDYNAMIC) && (el->pos.x >= pos.x - radius) && (el->pos.x <= pos.x + radius) && (el->pos.z >= pos.z - radius) && (el->pos.z <= pos.z + radius) ) { RecalcLight(el); g_culledStaticLights[g_culledStaticLightsCount] = el; g_culledStaticLightsCount++; if(g_culledStaticLightsCount >= g_dynamicLightsMax) g_culledStaticLightsCount--; } } }
void PrecalcDynamicLighting(long x0, long z0, long x1, long z1) { ARX_PROFILE_FUNC(); TOTPDL = 0; float fx0 = ACTIVEBKG->Xdiv * (float)x0; float fz0 = ACTIVEBKG->Zdiv * (float)z0; float fx1 = ACTIVEBKG->Xdiv * (float)x1; float fz1 = ACTIVEBKG->Zdiv * (float)z1; for(size_t i = 0; i < MAX_DYNLIGHTS; i++) { EERIE_LIGHT * el = &DynLight[i]; if(el->exist && el->rgb.r >= 0.f) { if( el->pos.x >= fx0 && el->pos.x <= fx1 && el->pos.z >= fz0 && el->pos.z <= fz1 && closerThan(el->pos, ACTIVECAM->orgTrans.pos, ACTIVECAM->cdepth) ) { el->treat = 1; RecalcLight(el); PDL[TOTPDL] = el; TOTPDL++; if((size_t)TOTPDL >= MAX_DYNLIGHTS) TOTPDL--; } else if(el->treat) el->treat = 0; } } }
void PrecalcIOLighting(const Vec3f & pos, float radius) { TOTIOPDL = 0; for(size_t i = 0; i < MAX_LIGHTS; i++) { EERIE_LIGHT * el = GLight[i]; if( el && el->exist && el->m_ignitionStatus && !(el->extras & EXTRAS_SEMIDYNAMIC) && (el->pos.x >= pos.x - radius) && (el->pos.x <= pos.x + radius) && (el->pos.z >= pos.z - radius) && (el->pos.z <= pos.z + radius) ) { RecalcLight(el); IO_PDL[TOTIOPDL] = el; TOTIOPDL++; if(TOTIOPDL >= MAX_DYNLIGHTS) TOTIOPDL--; } } }
void PrecalcDynamicLighting(const Vec3f & camPos, float camDepth) { ARX_PROFILE_FUNC(); g_culledDynamicLightsCount = 0; BOOST_FOREACH(EERIE_LIGHT & light, g_dynamicLights) { if(light.m_exists && light.rgb != Color3f::black) { light.m_isVisible = closerThan(light.pos, camPos, camDepth + light.fallend); if(light.m_isVisible) { RecalcLight(&light); arx_assert(g_culledDynamicLightsCount < size_t(boost::size(g_culledDynamicLights))); g_culledDynamicLights[g_culledDynamicLightsCount++] = &light; } } } }
void TreatBackgroundDynlights() { ARX_PROFILE_FUNC(); for(size_t i = 0; i < MAX_LIGHTS; i++) { EERIE_LIGHT *light = GLight[i]; if(light && (light->extras & EXTRAS_SEMIDYNAMIC)) { float fMaxdist = player.m_telekinesis ? 850 : 300; if(!fartherThan(light->pos, ACTIVECAM->orgTrans.pos, fMaxdist)) { ComputeLight2DPos(light); } else { light->m_screenRect.max.x = -1; light->m_screenRect.min.x = 1; } if(!light->m_ignitionStatus) { // just extinguished if(lightHandleIsValid(light->m_ignitionLightHandle)) { lightHandleGet(light->m_ignitionLightHandle)->exist = 0; light->m_ignitionLightHandle = LightHandle(); for(size_t l = 0; l < entities.size(); l++) { const EntityHandle handle = EntityHandle(l); Entity * e = entities[handle]; if(e && (e->ioflags & IO_MARKER)) { Vec3f _pos2 = GetItemWorldPosition(e); if(!fartherThan(light->pos, _pos2, 300.f)) { SendIOScriptEvent(e, SM_CUSTOM, "douse"); } } } } } else { // just light up if(!lightHandleIsValid(light->m_ignitionLightHandle)) { for(size_t l = 0; l < entities.size(); l++) { const EntityHandle handle = EntityHandle(l); Entity * e = entities[handle]; if(e && (e->ioflags & IO_MARKER)) { Vec3f _pos2 = GetItemWorldPosition(e); if(!fartherThan(light->pos, _pos2, 300.f)) { SendIOScriptEvent(e, SM_CUSTOM, "fire"); } } } light->m_ignitionLightHandle = GetFreeDynLight(); } if(lightHandleIsValid(light->m_ignitionLightHandle)) { EERIE_LIGHT *dynamicLight = lightHandleGet(light->m_ignitionLightHandle); dynamicLight->pos = light->pos; dynamicLight->fallstart = light->fallstart; dynamicLight->fallend = light->fallend; dynamicLight->m_isIgnitionLight = true; dynamicLight->intensity = light->intensity; dynamicLight->ex_flaresize = light->ex_flaresize; dynamicLight->extras = light->extras; dynamicLight->duration = std::numeric_limits<long>::max(); dynamicLight->rgb = light->rgb - light->rgb * light->ex_flicker * randomColor3f() * 0.5f; dynamicLight->rgb = componentwise_max(dynamicLight->rgb, Color3f::black); RecalcLight(dynamicLight); } } } } for(size_t i = 0; i < MAX_DYNLIGHTS; i++) { EERIE_LIGHT * el = &DynLight[i]; if(el->exist && el->duration) { float tim = (float)float(arxtime) - (float)el->time_creation; float duration = (float)el->duration; if(tim >= duration) { float sub = framedelay * 0.001f; el->rgb.r -= sub; el->rgb.g -= sub; el->rgb.b -= sub; if(el->rgb.r < 0) el->rgb.r = 0.f; if(el->rgb.g < 0) el->rgb.g = 0.f; if(el->rgb.b < 0) el->rgb.b = 0.f; if(el->rgb.r + el->rgb.g + el->rgb.b == 0) { el->exist = 0; el->duration = 0; } } } } }
void ARX_INTERFACE_ManageOpenedBook_Finish() { Vec3f pos = Vec3f(0.f, 0.f, 2100.f); Anglef angle = Anglef::ZERO; EERIE_LIGHT * light = lightHandleGet(torchLightHandle); EERIE_LIGHT tl = *light; light->pos = Vec3f(500.f, -1960.f, 1590.f); light->exist = 1; light->rgb = Color3f(0.6f, 0.7f, 0.9f); light->intensity = 1.8f; light->fallstart=4520.f; light->fallend = light->fallstart + 600.f; RecalcLight(light); EERIE_CAMERA * oldcam = ACTIVECAM; PDL[0] = light; TOTPDL=1; Vec2i tmpPos = Vec2i_ZERO; for(size_t i = 0; i < RUNE_COUNT; i++) { if(!gui::necklace.runes[i]) continue; EERIE_3DOBJ * rune = gui::necklace.runes[i]; bookcam.center.x = (382 + tmpPos.x * 45 + BOOKDEC.x) * g_sizeRatio.x; bookcam.center.y = (100 + tmpPos.y * 64 + BOOKDEC.y) * g_sizeRatio.y; SetActiveCamera(&bookcam); PrepareCamera(&bookcam, g_size); // First draw the lace angle.setPitch(0.f); if(player.hasRune((Rune)i)) { TransformInfo t1(pos, glm::toQuat(toRotationMatrix(angle))); DrawEERIEInter(gui::necklace.lacet, t1, NULL); if(rune->angle.getPitch() != 0.f) { if(rune->angle.getPitch() > 300.f) rune->angle.setPitch(300.f); angle.setPitch(std::sin(arxtime.get_updated() * (1.0f / 200)) * rune->angle.getPitch() * (1.0f / 40)); } rune->angle.setPitch(rune->angle.getPitch() - framedelay * 0.2f); if(rune->angle.getPitch() < 0.f) rune->angle.setPitch(0.f); GRenderer->SetRenderState(Renderer::DepthWrite, true); GRenderer->SetRenderState(Renderer::AlphaBlending, false); // Now draw the rune TransformInfo t2(pos, glm::toQuat(toRotationMatrix(angle))); DrawEERIEInter(rune, t2, NULL); EERIE_2D_BBOX runeBox; UpdateBbox2d(*rune, runeBox); PopAllTriangleList(); tmpPos.x++; if(tmpPos.x > 4) { tmpPos.x = 0; tmpPos.y++; } const Rect runeMouseTestRect( runeBox.min.x, runeBox.min.y, runeBox.max.x, runeBox.max.y ); // Checks for Mouse floating over a rune... if(runeMouseTestRect.contains(Vec2i(DANAEMouse))) { long r=0; for(size_t j = 0; j < rune->facelist.size(); j++) { float n = PtIn2DPolyProj(rune, &rune->facelist[j], (float)DANAEMouse.x, (float)DANAEMouse.y); if(n!=0.f) { r=1; break; } } if(r) { GRenderer->SetRenderState(Renderer::AlphaBlending, true); GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne); TransformInfo t(pos, glm::toQuat(toRotationMatrix(angle))); DrawEERIEInter(rune, t, NULL); rune->angle.setPitch(rune->angle.getPitch() + framedelay*2.f); PopAllTriangleList(); GRenderer->SetRenderState(Renderer::AlphaBlending, false); SpecialCursor=CURSOR_INTERACTION_ON; if(eeMouseDown1()) if((size_t)LastRune != i) { PlayerBookDrawRune((Rune)i); } LastRune=i; } } } } GRenderer->SetCulling(Renderer::CullCCW); LastRune=-1; *light = tl; SetActiveCamera(oldcam); PrepareCamera(oldcam, g_size); }
void TreatBackgroundDynlights() { ARX_PROFILE_FUNC(); for(size_t i = 0; i < g_staticLightsMax; i++) { EERIE_LIGHT * light = g_staticLights[i]; if(light && (light->extras & EXTRAS_SEMIDYNAMIC)) { float fMaxdist = player.m_telekinesis ? 850 : 300; if(!fartherThan(light->pos, g_camera->m_pos, fMaxdist)) { ComputeLight2DPos(light); } else { light->m_screenRect = Rectf(1, 0, -1, 0); // Intentionally invalid } if(!light->m_ignitionStatus) { // just extinguished EERIE_LIGHT * dynLight = lightHandleGet(light->m_ignitionLightHandle); if(dynLight) { dynLight->m_exists = false; light->m_ignitionLightHandle = LightHandle(); for(size_t l = 0; l < entities.size(); l++) { const EntityHandle handle = EntityHandle(l); Entity * e = entities[handle]; if(e && (e->ioflags & IO_MARKER)) { Vec3f _pos2 = GetItemWorldPosition(e); if(!fartherThan(light->pos, _pos2, 300.f)) { SendIOScriptEvent(NULL, e, SM_CUSTOM, "douse"); } } } } } else { // just light up if(!lightHandleGet(light->m_ignitionLightHandle)) { for(size_t l = 0; l < entities.size(); l++) { const EntityHandle handle = EntityHandle(l); Entity * e = entities[handle]; if(e && (e->ioflags & IO_MARKER)) { Vec3f _pos2 = GetItemWorldPosition(e); if(!fartherThan(light->pos, _pos2, 300.f)) { SendIOScriptEvent(NULL, e, SM_CUSTOM, "fire"); } } } light->m_ignitionLightHandle = GetFreeDynLight(); } EERIE_LIGHT * dynamicLight = lightHandleGet(light->m_ignitionLightHandle); if(dynamicLight) { dynamicLight->pos = light->pos; dynamicLight->fallstart = light->fallstart; dynamicLight->fallend = light->fallend; dynamicLight->m_isIgnitionLight = true; dynamicLight->intensity = light->intensity; dynamicLight->ex_flaresize = light->ex_flaresize; dynamicLight->extras = light->extras; dynamicLight->duration = GameDurationMs(std::numeric_limits<long>::max()); dynamicLight->rgb = light->rgb - light->rgb * light->ex_flicker * randomColor3f() * 0.5f; dynamicLight->rgb = componentwise_max(dynamicLight->rgb, Color3f::black); RecalcLight(dynamicLight); } } } } for(size_t i = 0; i < g_dynamicLightsMax; i++) { EERIE_LIGHT * el = &g_dynamicLights[i]; if(el->m_exists && el->duration != 0) { const GameDuration elapsed = g_gameTime.now() - el->creationTime; const GameDuration duration = el->duration; if(elapsed >= duration) { float sub = g_gameTime.lastFrameDuration() / GameDurationMs(1000); el->rgb.r -= sub; el->rgb.g -= sub; el->rgb.b -= sub; if(el->rgb.r < 0) el->rgb.r = 0.f; if(el->rgb.g < 0) el->rgb.g = 0.f; if(el->rgb.b < 0) el->rgb.b = 0.f; if(el->rgb.r + el->rgb.g + el->rgb.b == 0) { el->m_exists = false; el->duration = 0; } } } } }
void ARX_INTERFACE_ManageOpenedBook_Finish(const Vec2f & mousePos, Rectf rect, float scale) { RenderState baseState = render3D().depthTest(false).fog(false); Vec3f pos = Vec3f(0.f, 0.f, 2100.f); EERIE_LIGHT * light = lightHandleGet(torchLightHandle); EERIE_LIGHT tl = *light; light->pos = Vec3f(500.f, -1960.f, 1590.f); light->m_exists = true; light->rgb = Color3f(0.6f, 0.7f, 0.9f); light->intensity = 1.8f; light->fallstart = 4520.f; light->fallend = light->fallstart + 600.f; RecalcLight(light); Camera * oldcam = g_camera; g_culledDynamicLights[0] = light; g_culledDynamicLightsCount = 1; Vec2i tmpPos(0); GRenderer->SetAntialiasing(true); float wave = timeWaveSin(g_platformTime.frameStart(), PlatformDurationMsf(1256.6370614f)); float ptDelta = toMs(g_platformTime.lastFrameDuration()); Camera bookcam; bookcam.angle = Anglef(); bookcam.m_pos = Vec3f(0.f); bookcam.focal = 500.f; bookcam.cdepth = 2200.f; for(size_t i = 0; i < RUNE_COUNT; i++) { if(!gui::necklace.runes[i]) continue; EERIE_3DOBJ * rune = gui::necklace.runes[i]; Vec2i projectionCenter = Vec2i(rect.topLeft() + (Vec2f(285, 36) + Vec2f(tmpPos) * Vec2f(45, 64)) * scale); PrepareCamera(&bookcam, Rect(rect), projectionCenter); if(player.hasRune((Rune)i)) { Anglef angle; if(rune->angle.getYaw() != 0.f) { if(rune->angle.getYaw() > 300.f) { rune->angle.setYaw(300.f); } angle.setYaw(wave * rune->angle.getYaw() * (1.0f / 40)); } rune->angle.setYaw(rune->angle.getYaw() - ptDelta * 0.2f); if(rune->angle.getYaw() < 0.f) rune->angle.setYaw(0.f); // Now draw the rune TransformInfo t2(pos, glm::quat_cast(toRotationMatrix(angle))); DrawEERIEInter(rune, t2, NULL, false, 0.f); Rectf runeBox = UpdateBbox2d(*rune).toRect(); PopAllTriangleListOpaque(baseState); tmpPos.x++; if(tmpPos.x > 4) { tmpPos.x = 0; tmpPos.y++; } // TODO this is a workaround for vertexClipPositions being relative to viewport Vec2f mousePosInViewport = mousePos - rect.topLeft(); // Checks for Mouse floating over a rune... if(runeBox.contains(mousePosInViewport)) { bool r = false; for(size_t j = 0; j < rune->facelist.size(); j++) { float n = PtIn2DPolyProj(rune->vertexClipPositions, &rune->facelist[j], mousePosInViewport.x, mousePosInViewport.y); if(n != 0.f) { r = true; break; } } if(r) { TransformInfo t(pos, glm::quat_cast(toRotationMatrix(angle))); DrawEERIEInter(rune, t, NULL, false, 0.f); rune->angle.setYaw(rune->angle.getYaw() + ptDelta * 2.f); PopAllTriangleListOpaque(baseState.blendAdditive()); cursorSetInteraction(); if(eeMouseDown1()) { PlayerBookDrawRune((Rune)i); } } } TransformInfo t1(pos, quat_identity()); DrawEERIEInter(gui::necklace.lacet, t1, NULL, false, 0.f); PopAllTriangleListOpaque(baseState); } } *light = tl; PrepareCamera(oldcam, g_size); GRenderer->SetAntialiasing(false); }