Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
TVector CCamera::GetCameraTarget()
{
	if (m_bFreeMode)
		return m_vecFreeCamera + AngleVector(m_angFreeCamera);

	return TVector(0,0,0);
}
Ejemplo n.º 3
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);
	}
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
TVector CCharacterCamera::GetThirdPersonCameraDirection()
{
	CCharacter* pCharacter = m_hCharacter;

	if (!pCharacter)
		return TVector();

	return AngleVector(pCharacter->GetThirdPersonCameraAngles());
}
Ejemplo n.º 6
0
			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);
				}
			}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
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();
}
Ejemplo n.º 10
0
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
}
Ejemplo n.º 11
0
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();
		}
	}
}
Ejemplo n.º 12
0
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;
	}
}
Ejemplo n.º 13
0
Archivo: ao.cpp Proyecto: ezhangle/SMAK
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.
}
Ejemplo n.º 14
0
Vector CToyEditor::GetCameraDirection()
{
	return AngleVector(m_angPreview);
}