bool CStructure::CanAutoCloseMenu() const { CPlayerCharacter* pOwner = GetOwner()->GetPlayerCharacter(); if (!pOwner) return false; if (GetOwner()->IsInBlockPlaceMode()) return true; if (GetOwner()->IsInBlockDesignateMode()) return true; if (GetOwner()->IsInConstructionMode()) return true; TVector vecPlayerEyes = pOwner->GetLocalOrigin() + pOwner->EyeHeight() * DoubleVector(pOwner->GetLocalUpVector()); TVector vecOwnerProjectionPoint = GetLocalOrigin() + GetLocalTransform().TransformVector(GameData().GetCommandMenuRenderOffset()); Vector vecToPlayerEyes = (vecPlayerEyes - vecOwnerProjectionPoint).GetMeters(); float flDistanceToPlayerEyes = vecToPlayerEyes.Length(); Vector vecProjectionDirection = vecToPlayerEyes/flDistanceToPlayerEyes; float flViewAngleDot = AngleVector(pOwner->GetViewAngles()).Dot(vecProjectionDirection); if (GameData().GetCommandMenu() && (GameData().GetCommandMenu()->WantsToClose() || flDistanceToPlayerEyes > 5 || flViewAngleDot > -0.7)) return true; return false; }
TVector CCamera::GetCameraTarget() { if (m_bFreeMode) return m_vecFreeCamera + AngleVector(m_angFreeCamera); return TVector(0,0,0); }
void CLaser::PostRender() const { BaseClass::PostRender(); if (!GameServer()->GetRenderer()->IsRenderingTransparent()) return; if (!m_bShouldRender) return; if (!m_hOwner) return; CRenderingContext r(DigitanksGame()->GetDigitanksRenderer(), true); r.SetBlend(BLEND_ADDITIVE); Vector vecForward, vecRight, vecUp; float flLength = LaserLength(); CDigitank* pOwner = dynamic_cast<CDigitank*>(GetOwner()); Vector vecMuzzle = m_hOwner->GetGlobalOrigin(); Vector vecTarget = vecMuzzle + AngleVector(GetGlobalAngles()) * flLength; if (pOwner) { Vector vecDirection = (pOwner->GetLastAim() - pOwner->GetGlobalOrigin()).Normalized(); vecTarget = vecMuzzle + vecDirection * flLength; AngleVectors(VectorAngles(vecDirection), &vecForward, &vecRight, &vecUp); vecMuzzle = pOwner->GetGlobalOrigin() + vecDirection * 3 + Vector(0, 0, 3); } float flBeamWidth = 1.5; Vector avecRayColors[] = { Vector(1, 0, 0), Vector(0, 1, 0), Vector(0, 0, 1), }; float flRayRamp = RemapValClamped((float)(GameServer()->GetGameTime() - GetSpawnTime()), 0.5f, 1.5f, 0.0f, 1); float flAlphaRamp = RemapValClamped((float)(GameServer()->GetGameTime() - GetSpawnTime()), 1, 2, 1.0f, 0); size_t iBeams = 21; for (size_t i = 0; i < iBeams; i++) { float flUp = RemapVal((float)i, 0, (float)iBeams, -flLength, flLength); Vector vecRay = LerpValue<Vector>(Vector(1, 1, 1), avecRayColors[i%3], flRayRamp); Color clrRay = vecRay; clrRay.SetAlpha((int)(200*flAlphaRamp)); r.SetColor(clrRay); CRopeRenderer rope(DigitanksGame()->GetDigitanksRenderer(), s_hBeam, vecMuzzle, flBeamWidth); rope.SetTextureOffset(((float)i/20) - GameServer()->GetGameTime() - GetSpawnTime()); rope.Finish(vecTarget + vecUp*flUp); } }
bool CStructure::CanAutoOpenMenu() const { CPlayerCharacter* pOwner = GetOwner()->GetPlayerCharacter(); if (!pOwner) return false; if (GetOwner()->IsInBlockPlaceMode()) return false; if (GetOwner()->IsInBlockDesignateMode()) return false; if (GetOwner()->IsInConstructionMode()) return false; TVector vecPlayerEyes = pOwner->GetLocalOrigin() + pOwner->EyeHeight() * DoubleVector(pOwner->GetLocalUpVector()); TVector vecOwnerProjectionPoint = GetLocalOrigin() + GetLocalTransform().TransformVector(GameData().GetCommandMenuRenderOffset()); Vector vecToPlayerEyes = (vecPlayerEyes - vecOwnerProjectionPoint).GetMeters(); float flDistanceToPlayerEyes = vecToPlayerEyes.Length(); Vector vecProjectionDirection = vecToPlayerEyes/flDistanceToPlayerEyes; float flViewAngleDot = AngleVector(pOwner->GetViewAngles()).Dot(vecProjectionDirection); CSPPlayer* pPlayerOwner = static_cast<CSPPlayer*>(pOwner->GetControllingPlayer()); if (!GameData().GetCommandMenu() && flDistanceToPlayerEyes < 4 && flViewAngleDot < -0.8 && !pPlayerOwner->GetActiveCommandMenu()) return true; return false; }
TVector CCharacterCamera::GetThirdPersonCameraDirection() { CCharacter* pCharacter = m_hCharacter; if (!pCharacter) return TVector(); return AngleVector(pCharacter->GetThirdPersonCameraAngles()); }
inline void moveCamera() { camera_->rotate(AngleVector(-rotY_.valueDegrees(), rotX_.valueDegrees(), 0.0)); camera_->translate(camera_->getOrientation().yawOrientation * translateVector_); const double maxPitch = 60.0; AngleVector rotation = camera_->getRotation(); const double pitch = rotation.pitch; // Limit the pitch. if(fabs(pitch) > maxPitch) { rotation.pitch = (pitch > 0.0) ? maxPitch : -maxPitch; camera_->setRotation(rotation); } }
TVector CToyEditor::GetCameraPosition() { CModel* pMesh = CModelLibrary::GetModel(m_iMeshPreview); Vector vecPreviewAngle = AngleVector(m_angPreview)*m_flPreviewDistance; if (!pMesh) { CModel* pPhys = CModelLibrary::GetModel(m_iPhysPreview); if (!pPhys) return Vector(0, 0, 0) - vecPreviewAngle; return pPhys->m_aabbVisBoundingBox.Center() - vecPreviewAngle; } return pMesh->m_aabbVisBoundingBox.Center() - vecPreviewAngle; }
void CSystemInstance::SpawnParticle() { m_iNumParticlesAlive++; m_iTotalEmitted++; CParticle* pNewParticle = NULL; for (size_t i = 0; i < m_aParticles.size(); i++) { CParticle* pParticle = &m_aParticles[i]; if (pParticle->m_bActive) continue; pNewParticle = pParticle; break; } if (!pNewParticle) { m_aParticles.push_back(CParticle()); pNewParticle = &m_aParticles[m_aParticles.size()-1]; } Vector vecDistance = Vector(0,0,0); if (m_pSystem->GetEmissionMaxDistance() > 0) { float flYaw = RandomFloat(-180, 180); float flDistance = cos(RandomFloat(0, M_PI/2)) * m_pSystem->GetEmissionMaxDistance(); float flPitch = sin(RandomFloat(-M_PI/2, M_PI/2)) * 90; vecDistance = AngleVector(EAngle(flPitch, flYaw, 0)) * flDistance; } pNewParticle->Reset(); pNewParticle->m_vecOrigin = m_vecOrigin + m_pSystem->GetSpawnOffset() + vecDistance; pNewParticle->m_vecVelocity = m_vecInheritedVelocity * m_pSystem->GetInheritedVelocity(); if (m_pSystem->GetRandomVelocity().Size().LengthSqr() > 0) { Vector vecMins = m_pSystem->GetRandomVelocity().m_vecMins; Vector vecMaxs = m_pSystem->GetRandomVelocity().m_vecMaxs; pNewParticle->m_vecVelocity.x += RandomFloat(vecMins.x, vecMaxs.x); pNewParticle->m_vecVelocity.y += RandomFloat(vecMins.y, vecMaxs.y); pNewParticle->m_vecVelocity.z += RandomFloat(vecMins.z, vecMaxs.z); } pNewParticle->m_angAngles = m_angAngles; if (m_pSystem->GetRandomModelYaw()) pNewParticle->m_angAngles.y = RandomFloat(0, 360); if (m_pSystem->GetRandomModelRoll()) pNewParticle->m_angAngles.r = RandomFloat(-180, 180); if (m_pSystem->GetRandomAngleVelocity()) pNewParticle->m_angAngleVelocity = EAngle(RandomFloat(-90, 90), RandomFloat(-180, 180), RandomFloat(-90, 90)); if (m_pSystem->GetFadeIn()) pNewParticle->m_flAlpha = 0; else pNewParticle->m_flAlpha = m_pSystem->GetAlpha(); pNewParticle->m_flRadius = m_pSystem->GetStartRadius(); if (m_pSystem->GetRandomBillboardYaw()) pNewParticle->m_flBillboardYaw = RandomFloat(0, 360); else pNewParticle->m_flBillboardYaw = 0; }
void CTexelAOMethod::GenerateTexel(size_t iTexel, CConversionMeshInstance* pMeshInstance, CConversionFace* pFace, CConversionVertex* pV1, CConversionVertex* pV2, CConversionVertex* pV3, raytrace::CTraceResult* tr, const Vector& vecUVPosition, raytrace::CRaytracer* pTracer) { CConversionFace* pHitFace = tr->m_pMeshInstance->GetMesh()->GetFace(tr->m_iFace); Vector vecHitNormal = pHitFace->GetNormal(tr->m_vecHit, tr->m_pMeshInstance); // Build rotation matrix Matrix4x4 m; m.SetOrientation(vecHitNormal); // Turn it sideways so that pitch 90 is up Matrix4x4 m2; m2.SetAngles(EAngle(-90, 0, 0)); m *= m2; //SMAKWindow()->AddDebugLine(vecUVPosition + pFace->GetNormal()*0.01f, vecUVPosition + vecNormal*0.5f, Color(0, 0, 255)); float flHits = 0; float flTotalHits = 0; for (size_t x = 0; x < m_iSamples/2; x++) { float flRandom = 0; if (m_bRandomize) flRandom = RemapVal((float)(rand()%10000), 0, 10000.0f, -0.5f, 0.5f); float flPitch = RemapVal(cos(RemapVal((float)x+flRandom, 0, (float)m_iSamples/2, 0, (float)M_PI/2)), 0, 1, 90, 0); float flWeight = sin(flPitch * M_PI/180); for (size_t y = 0; y <= m_iSamples; y++) { flRandom = 0; if (m_bRandomize) flRandom = RemapVal((float)(rand()%10000), 0, 10000.0f, -0.5f, 0.5f); float flYaw = RemapVal((float)y+flRandom, 0, (float)m_iSamples, -180, 180); Vector vecDir = AngleVector(EAngle(flPitch, flYaw, 0)); // Transform relative to the triangle's normal Vector vecRay = m * vecDir; flTotalHits += flWeight; //SMAKWindow()->AddDebugLine(vecUVPosition + pFace->GetNormal()*0.01f, vecUVPosition + vecRay.Normalized()*0.1f, vecDir); raytrace::CTraceResult tr2; if (pTracer->Raytrace(Ray(tr->m_vecHit + vecHitNormal*0.01f, vecRay), &tr2)) { float flDistance = (tr2.m_vecHit - tr->m_vecHit).Length(); if (m_flRayFalloff < 0) flHits += flWeight; else flHits += flWeight * (1/pow(2, flDistance/m_flRayFalloff)); } else if (m_bGroundOcclusion && vecRay.y < 0) { // The following math is basically a plane-ray intersection algorithm, // with shortcuts made for the assumption of an infinite plane facing straight up. Vector n = Vector(0,1,0); float a = -(vecUVPosition.y - pMeshInstance->m_pParent->m_oExtends.m_vecMins.y); float b = vecRay.y; float flDistance = a/b; if (flDistance < 1e-4f || m_flRayFalloff < 0) flHits += flWeight; else flHits += flWeight * (1/pow(2, flDistance/m_flRayFalloff)); } } } // One last ray directly up, it is skipped in the above loop so it's not done 10 times. Vector vecDir = AngleVector(EAngle(90, 0, 0)); // Transform relative to the triangle's normal Vector vecRay = m * vecDir; //RenderSceneFromPosition(vecUVPosition, vecRay, pFace); flTotalHits++; //SMAKWindow()->AddDebugLine(vecUVPosition + pFace->GetNormal()*0.01f, vecUVPosition + vecRay.Normalized()*0.2f, vecDir); raytrace::CTraceResult tr2; if (pTracer->Raytrace(Ray(tr->m_vecHit + vecHitNormal*0.01f, vecRay), &tr2)) { float flDistance = (tr2.m_vecHit - tr->m_vecHit).Length(); if (m_flRayFalloff < 0) flHits += 1; else flHits += (1/pow(2, flDistance/m_flRayFalloff)); } else if (m_bGroundOcclusion && vecRay.y < 0) { // The following math is basically a plane-ray intersection algorithm, // with shortcuts made for the assumption of an infinite plane facing straight up. float a = -(tr->m_vecHit.y - pMeshInstance->m_pParent->m_oExtends.m_vecMins.y); float b = vecRay.y; float flDistance = a/b; if (flDistance < 1e-4f || m_flRayFalloff < 0) flHits += 1; else flHits += (1/pow(2, flDistance/m_flRayFalloff)); } float flShadowValue = 1 - ((float)flHits / (float)flTotalHits); // Mutex may be dead, try to bail before. if (m_pGenerator->IsStopped()) return; m_pGenerator->GetParallelizer()->LockData(); m_avecShadowValues[iTexel] += Vector(flShadowValue, flShadowValue, flShadowValue); m_aiShadowReads[iTexel]++; m_pGenerator->MarkTexelUsed(iTexel); m_pGenerator->GetParallelizer()->UnlockData(); }
void CSupplier::UpdateTendrils() { if (IsConstructing()) return; TStubbed("Tendrils"); #if 0 if (!GetPlayerOwner()) { if (m_iTendrilsCallList) glDeleteLists((GLuint)m_iTendrilsCallList, 1); m_iTendrilsCallList = 0; DigitanksGame()->GetTerrain()->DirtyChunkTexturesWithinDistance(GetGlobalOrigin(), GetDataFlowRadius() + GetBoundingRadius()); return; } if (GameServer()->IsLoading()) return; bool bUpdateTerrain = false; size_t iRadius = (size_t)GetDataFlowRadius(); while (m_aTendrils.size() < iRadius) { m_aTendrils.push_back(CTendril()); CTendril* pTendril = &m_aTendrils[m_aTendrils.size()-1]; pTendril->m_flLength = (float)m_aTendrils.size() + GetBoundingRadius(); pTendril->m_vecEndPoint = DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin() + AngleVector(EAngle(0, RandomFloat(0, 360), 0)) * pTendril->m_flLength); pTendril->m_flScale = RandomFloat(3, 7); pTendril->m_flOffset = RandomFloat(0, 1); pTendril->m_flSpeed = RandomFloat(0.5f, 2); bUpdateTerrain = true; } if (bUpdateTerrain) DigitanksGame()->GetTerrain()->DirtyChunkTexturesWithinDistance(GetGlobalOrigin(), GetDataFlowRadius() + GetBoundingRadius()); if (m_iTendrilsCallList) glDeleteLists((GLuint)m_iTendrilsCallList, 1); m_iTendrilsCallList = glGenLists(1); Color clrTeam = GetPlayerOwner()->GetColor(); clrTeam = (Vector(clrTeam) + Vector(1,1,1))/2; glNewList((GLuint)m_iTendrilsCallList, GL_COMPILE); for (size_t i = 0; i < m_aTendrils.size(); i++) { // Only show the longest tendrils, for perf reasons. if (i < iRadius - 15) continue; CTendril* pTendril = &m_aTendrils[i]; Vector vecDestination = pTendril->m_vecEndPoint; Vector vecPath = vecDestination - GetGlobalOrigin(); vecPath.y = 0; float flDistance = vecPath.Length2D(); Vector vecDirection = vecPath.Normalized(); size_t iSegments = (size_t)(flDistance/3); GLuint iScrollingTextureProgram = (GLuint)CShaderLibrary::GetScrollingTextureProgram(); GLuint flSpeed = glGetUniformLocation(iScrollingTextureProgram, "flSpeed"); glUniform1f(flSpeed, pTendril->m_flSpeed); clrTeam.SetAlpha(105); CRopeRenderer oRope(GameServer()->GetRenderer(), s_iTendrilBeam, DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin()) + Vector(0, 0, 1), 1.0f); oRope.SetColor(clrTeam); oRope.SetTextureScale(pTendril->m_flScale); oRope.SetTextureOffset(pTendril->m_flOffset); oRope.SetForward(Vector(0, 0, -1)); for (size_t i = 1; i < iSegments; i++) { clrTeam.SetAlpha((int)RemapVal((float)i, 1, (float)iSegments, 100, 30)); oRope.SetColor(clrTeam); float flCurrentDistance = ((float)i*flDistance)/iSegments; oRope.AddLink(DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin() + vecDirection*flCurrentDistance) + Vector(0, 0, 1)); } oRope.Finish(DigitanksGame()->GetTerrain()->GetPointHeight(vecDestination) + Vector(0, 0, 1)); } glEndList(); #endif }
void CLaser::OnSetOwner(CBaseEntity* pOwner) { BaseClass::OnSetOwner(pOwner); CDigitank* pTank = dynamic_cast<CDigitank*>(pOwner); if (!pTank) return; SetGlobalAngles(VectorAngles((pTank->GetLastAim() - GetGlobalOrigin()).Normalized())); SetGlobalOrigin(pOwner->GetGlobalOrigin()); SetGlobalVelocity(Vector(0,0,0)); SetGlobalGravity(Vector(0,0,0)); m_flTimeExploded = GameServer()->GetGameTime(); Vector vecForward, vecRight; AngleVectors(GetGlobalAngles(), &vecForward, &vecRight, NULL); for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++) { CBaseEntity* pEntity = CBaseEntity::GetEntity(i); if (!pEntity) continue; if (!pEntity->TakesDamage()) continue; if (pEntity->GetOwner() == pOwner->GetOwner()) continue; float flDistance = DistanceToPlane(pEntity->GetGlobalOrigin(), GetGlobalOrigin(), vecRight); if (flDistance > 4 + pEntity->GetBoundingRadius()) continue; // Cull objects behind if (vecForward.Dot(pEntity->GetGlobalOrigin() - GetGlobalOrigin()) < 0) continue; if (pEntity->Distance(GetGlobalOrigin()) > LaserLength()) continue; pEntity->TakeDamage(pOwner, this, DAMAGE_LASER, m_flDamage, flDistance < pEntity->GetBoundingRadius()-2); CDigitank* pTank = dynamic_cast<CDigitank*>(pEntity); if (pTank) { float flRockIntensity = 0.5f; Vector vecDirection = (pTank->GetGlobalOrigin() - pOwner->GetGlobalOrigin()).Normalized(); pTank->RockTheBoat(flRockIntensity, vecDirection); } } CDigitanksPlayer* pCurrentTeam = DigitanksGame()->GetCurrentLocalDigitanksPlayer(); if (pCurrentTeam && pCurrentTeam->GetVisibilityAtPoint(GetGlobalOrigin()) < 0.1f) { if (pCurrentTeam->GetVisibilityAtPoint(GetGlobalOrigin() + AngleVector(GetGlobalAngles())*LaserLength()) < 0.1f) { // If the start and end points are both in the fog of war, delete it now that we've aready done the damage so it doesn't get rendered later. if (GameNetwork()->IsHost()) Delete(); } } }
void CLaser::ClientSpawn() { BaseClass::ClientSpawn(); if (DigitanksGame()->GetCurrentLocalDigitanksPlayer()->GetVisibilityAtPoint(GetGlobalOrigin()) < 0.1f) { if (DigitanksGame()->GetCurrentLocalDigitanksPlayer()->GetVisibilityAtPoint(GetGlobalOrigin() + AngleVector(GetGlobalAngles())*LaserLength()) < 0.1f) m_bShouldRender = false; } }
void CAOGenerator::GenerateShadowMaps() { double flProcessSceneRead = 0; double flProgress = 0; size_t iShadowMapSize = 1024; // A frame buffer for holding the depth buffer shadow render CFrameBuffer oDepthFB = SMAKRenderer()->CreateFrameBuffer(iShadowMapSize, iShadowMapSize, (fb_options_e)(FB_DEPTH_TEXTURE|FB_RENDERBUFFER)); // RB unused // A frame buffer for holding the UV layout once it is rendered flat with the shadow CFrameBuffer oUVFB = SMAKRenderer()->CreateFrameBuffer(m_iWidth, m_iHeight, (fb_options_e)(FB_TEXTURE|FB_LINEAR|FB_DEPTH)); // Depth unused // A frame buffer for holding the completed AO map m_oAOFB = SMAKRenderer()->CreateFrameBuffer(m_iWidth, m_iHeight, (fb_options_e)(FB_TEXTURE|FB_TEXTURE_HALF_FLOAT|FB_LINEAR|FB_DEPTH)); // Depth unused CRenderingContext c(SMAKRenderer()); c.UseFrameBuffer(&m_oAOFB); c.ClearColor(Color(0, 0, 0, 0)); c.SetDepthFunction(DF_LEQUAL); c.SetDepthTest(true); c.SetBackCulling(false); Matrix4x4 mBias( 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f); // Bias from [-1, 1] to [0, 1] AABB oBox = m_pScene->m_oExtends; Vector vecCenter = oBox.Center(); float flSize = oBox.Size().Length(); // Length of the box's diagonal Matrix4x4 mLightProjection = Matrix4x4::ProjectOrthographic(-flSize/2, flSize/2, -flSize/2, flSize/2, 1, flSize*2); size_t iSamples = (size_t)sqrt((float)m_iSamples); m_pWorkListener->SetAction("Taking exposures", m_iSamples); for (size_t x = 0; x <= iSamples; x++) { float flPitch = -asin(RemapVal((float)x, 0, (float)iSamples, -1, 1)) * 90 / (M_PI/2); for (size_t y = 0; y < iSamples; y++) { if (x == 0 || x == iSamples) { // Don't do a bunch of samples from the same spot on the poles. if (y != 0) continue; } float flYaw = RemapVal((float)y, 0, (float)iSamples, -180, 180); // Randomize the direction a tad to help fight moire Vector vecDir = AngleVector(EAngle(flPitch+RandomFloat(-1, 1)/2, flYaw+RandomFloat(-1, 1)/2, 0)); Vector vecLightPosition = vecDir*flSize + vecCenter; // Puts us twice as far from the closest vertex if (ao_debug.GetInt() > 1) SMAKWindow()->AddDebugLine(vecLightPosition, vecLightPosition-vecDir); Matrix4x4 mLightView = Matrix4x4::ConstructCameraView(vecLightPosition, (vecCenter-vecLightPosition).Normalized(), Vector(0, 1, 0)); c.SetProjection(mLightProjection); c.SetView(mLightView); // If we're looking from below and ground occlusion is on, don't bother with this render. if (!(flPitch < -10 && m_bGroundOcclusion)) { c.UseProgram("model"); c.UseFrameBuffer(&oDepthFB); c.SetViewport(Rect(0, 0, iShadowMapSize, iShadowMapSize)); c.SetBackCulling(false); c.ClearDepth(); c.BeginRenderVertexArray(m_iSceneDepth); c.SetPositionBuffer((size_t)0, 8*sizeof(float)); c.SetNormalsBuffer((size_t)3*sizeof(float), 8*sizeof(float)); c.SetTexCoordBuffer((size_t)6*sizeof(float), 8*sizeof(float)); c.EndRenderVertexArray(m_iSceneDepthVerts); c.UseFrameBuffer(nullptr); if (ao_debug.GetBool()) { CRenderingContext c(SMAKRenderer()); c.SetViewport(Rect(0, 0, iShadowMapSize/2, iShadowMapSize/2)); DrawTexture(oDepthFB.m_iDepthTexture, 1, c); } } Matrix4x4 mTextureMatrix = mBias*mLightProjection*mLightView; { CRenderingContext c(SMAKRenderer(), true); c.UseFrameBuffer(&oUVFB); c.SetViewport(Rect(0, 0, m_iWidth, m_iHeight)); c.ClearColor(Color(0, 0, 0, 0)); c.ClearDepth(); c.UseProgram("flat_shadow"); c.SetUniform("mBiasedLightMatrix", mTextureMatrix); c.SetUniform("iShadowMap", 0); c.SetUniform("vecLightNormal", -vecDir); c.SetUniform("bOccludeAll", (flPitch < -10 && m_bGroundOcclusion)); c.SetUniform("flTime", (float)Application()->GetTime()); c.BindTexture(oDepthFB.m_iDepthTexture); c.BeginRenderVertexArray(m_iScene); c.SetPositionBuffer((size_t)0, 8*sizeof(float)); c.SetNormalsBuffer((size_t)3*sizeof(float), 8*sizeof(float)); c.SetTexCoordBuffer((size_t)6*sizeof(float), 8*sizeof(float)); c.EndRenderVertexArray(m_iSceneVerts); } if (ao_debug.GetBool()) { CRenderingContext c(SMAKRenderer()); c.SetViewport(Rect(iShadowMapSize/2, 0, m_iWidth, m_iHeight)); DrawTexture(oUVFB.m_iMap, 1, c); } double flTimeBefore = SMAKWindow()->GetTime(); c.SetViewport(Rect(0, 0, m_iWidth, m_iHeight)); c.UseFrameBuffer(&m_oAOFB); AccumulateTexture(oUVFB.m_iMap); c.UseFrameBuffer(nullptr); if (ao_debug.GetBool()) { CRenderingContext c(SMAKRenderer()); c.UseProgram("ao"); c.SetViewport(Rect(iShadowMapSize/2+m_iWidth, 0, m_iWidth, m_iHeight)); c.SetUniform("iAOMap", 0); c.SetBlend(BLEND_ALPHA); DrawTexture(m_oAOFB.m_iMap, 1, c); } flProcessSceneRead += (SMAKWindow()->GetTime() - flTimeBefore); flTimeBefore = SMAKWindow()->GetTime(); m_pWorkListener->WorkProgress(x*iSamples + y); flProgress += (SMAKWindow()->GetTime() - flTimeBefore); if (m_bStopGenerating) break; } if (m_bStopGenerating) break; } c.UseFrameBuffer(&m_oAOFB); c.ReadPixels(0, 0, m_iWidth, m_iHeight, m_pvecPixels); c.UseFrameBuffer(nullptr); if (!m_bStopGenerating) { size_t iBufferSize = m_iWidth*m_iHeight; m_pWorkListener->SetAction("Reading pixels", iBufferSize); for (size_t p = 0; p < iBufferSize; p++) { Vector4D& vecPixel = m_pvecPixels[p]; if (vecPixel.w == 0.0f) continue; m_avecShadowValues[p].x = vecPixel.x; m_aiShadowReads[p] = (size_t)vecPixel.w; m_bPixelMask[p] = true; m_pWorkListener->WorkProgress(p); } } oDepthFB.Destroy(); oUVFB.Destroy(); // Don't destroy m_oAOFB yet, we need it in a bit. It gets destroyed later. }
Vector CToyEditor::GetCameraDirection() { return AngleVector(m_angPreview); }