Exemplo n.º 1
0
TRS CLevelEntity::CalculateGlobalTRS(CLevelEntity* pThis)
{
	TRS trsLocal;

	tstring sLocalOrigin = pThis->GetParameterValue("Origin");
	if (sLocalOrigin.length() && CanUnserializeString_TVector(sLocalOrigin))
		trsLocal.m_vecTranslation = UnserializeString_TVector(sLocalOrigin);

	tstring sLocalAngles = pThis->GetParameterValue("Angles");
	if (sLocalAngles.length() && CanUnserializeString_EAngle(sLocalAngles))
		trsLocal.m_angRotation = UnserializeString_EAngle(sLocalAngles);

	tstring sScale = pThis->GetParameterValue("Scale");
	if (sScale.length() && CanUnserializeString_TVector(sScale))
		trsLocal.m_vecScaling = UnserializeString_TVector(sScale);

	tstring sAABB = pThis->GetParameterValue("BoundingBox");
	if (CanUnserializeString_AABB(sAABB))
	{
		AABB aabbBounds = UnserializeString_AABB(sAABB, pThis->GetName(), pThis->m_sClass, "BoundingBox");

		// Center the entity around this bounding box.
		trsLocal.m_vecTranslation += aabbBounds.Center();
	}

	return trsLocal;
}
Exemplo n.º 2
0
Matrix4x4 CLevelEntity::CalculateGlobalTransform(CLevelEntity* pThis)
{
	Matrix4x4 mLocal;

	tstring sLocalOrigin = pThis->GetParameterValue("Origin");
	if (sLocalOrigin.length() && CanUnserializeString_TVector(sLocalOrigin))
		mLocal.SetTranslation(UnserializeString_TVector(sLocalOrigin));

	tstring sLocalAngles = pThis->GetParameterValue("Angles");
	if (sLocalAngles.length() && CanUnserializeString_EAngle(sLocalAngles))
		mLocal.SetAngles(UnserializeString_EAngle(sLocalAngles));

	tstring sAABB = pThis->GetParameterValue("BoundingBox");
	if (CanUnserializeString_AABB(sAABB))
	{
		AABB aabbBounds = UnserializeString_AABB(sAABB, pThis->GetName(), pThis->m_sClass, "BoundingBox");

		// Center the entity around this bounding box.
		Vector vecGlobalOrigin = aabbBounds.Center();
		mLocal.SetTranslation(mLocal.GetTranslation() + vecGlobalOrigin);

		Vector vecNewOrigin = mLocal.GetTranslation();
		pThis->SetParameterValue("Origin", pretty_float(vecNewOrigin.x) + " " + pretty_float(vecNewOrigin.y) + " " + pretty_float(vecNewOrigin.z));

		aabbBounds.m_vecMins -= vecGlobalOrigin;
		aabbBounds.m_vecMaxs -= vecGlobalOrigin;
		pThis->SetParameterValue("BoundingBox",
			pretty_float(aabbBounds.m_vecMins.x) + " " + pretty_float(aabbBounds.m_vecMins.y) + " " + pretty_float(aabbBounds.m_vecMins.z) + " "
			+ pretty_float(aabbBounds.m_vecMaxs.x) + " " + pretty_float(aabbBounds.m_vecMaxs.y) + " " + pretty_float(aabbBounds.m_vecMaxs.z));
	}

	return mLocal;
}
Exemplo n.º 3
0
Vector CToy::GetPhysicsBoxHalfSize(size_t iBox)
{
	TRS& trs = GetPhysicsBox(iBox);

	TAssert(trs.m_angRotation.p == 0);
	TAssert(trs.m_angRotation.y == 0);
	TAssert(trs.m_angRotation.r == 0);

	Matrix4x4 mTRS = trs.GetMatrix4x4();

	AABB aabbBox = s_aabbBoxDimensions;
	aabbBox.m_vecMins = mTRS*aabbBox.m_vecMins;
	aabbBox.m_vecMaxs = mTRS*aabbBox.m_vecMaxs;

	return aabbBox.m_vecMaxs - aabbBox.Center();
}
Exemplo n.º 4
0
AABB CLevelEntity::CalculateBoundingBox(CLevelEntity* pThis)
{
	size_t iModel = pThis->GetModelID();
	CModel* pModel = CModelLibrary::GetModel(iModel);

	if (pModel)
		return pModel->m_aabbVisBoundingBox;

	tstring sAABB = pThis->GetParameterValue("BoundingBox");

	AABB aabbBounds = AABB(Vector(-0.5f, -0.5f, -0.5f), Vector(0.5f, 0.5f, 0.5f));

	if (CanUnserializeString_AABB(sAABB))
	{
		aabbBounds = UnserializeString_AABB(sAABB, pThis->GetName(), pThis->m_sClass, "BoundingBox");

		// Center the entity around this bounding box.
		Vector vecGlobalOrigin = aabbBounds.Center();
		aabbBounds.m_vecMins -= vecGlobalOrigin;
		aabbBounds.m_vecMaxs -= vecGlobalOrigin;
	}
	else
	{
		CSaveData* pSaveData = CBaseEntity::FindSaveDataByHandle(tstring("C"+pThis->m_sClass).c_str(), "BoundingBox");
		if (pSaveData && pSaveData->m_bDefault)
			memcpy(&aabbBounds, &pSaveData->m_oDefault, sizeof(aabbBounds));
	}

	if (pThis->m_hMaterialModel.IsValid() && pThis->m_hMaterialModel->m_ahTextures.size())
	{
		CTextureHandle hBaseTexture = pThis->m_hMaterialModel->m_ahTextures[0];

		if (hBaseTexture.IsValid())
		{
			aabbBounds.m_vecMaxs.y *= (float)hBaseTexture->m_iHeight/pThis->m_hMaterialModel->m_iTexelsPerMeter;
			aabbBounds.m_vecMins.y *= (float)hBaseTexture->m_iHeight/pThis->m_hMaterialModel->m_iTexelsPerMeter;

			aabbBounds.m_vecMaxs.z *= (float)hBaseTexture->m_iWidth/pThis->m_hMaterialModel->m_iTexelsPerMeter;
			aabbBounds.m_vecMins.z *= (float)hBaseTexture->m_iWidth/pThis->m_hMaterialModel->m_iTexelsPerMeter;
		}
	}

	aabbBounds.m_vecMins = aabbBounds.m_vecMins * pThis->GetScale();
	aabbBounds.m_vecMaxs = aabbBounds.m_vecMaxs * pThis->GetScale();

	return aabbBounds;
}
Exemplo n.º 5
0
bool ConvexHullIntersectsAABB(const AABB& box, const tvector<vec3>& avecPoints, const tvector<size_t>& aiTriangles)
{
	TAssert(aiTriangles.size() % 3 == 0);

	vec3 vecCenter = box.Center();
	vec3 n;

	for (size_t i = 0; i < aiTriangles.size(); i += 3)
	{
		const vec3& v1 = avecPoints[aiTriangles[i]];
		const vec3& v2 = avecPoints[aiTriangles[i+1]];
		const vec3& v3 = avecPoints[aiTriangles[i+2]];

		n = (v2-v1).Cross(v3-v1).Normalized();

		if (n.Dot(vecCenter-v1) < 0)
			continue;

		if (!TriangleIntersectsAABB(box, v1, v2, v3))
			return false;
	}

	return true;
}
Exemplo n.º 6
0
bool RayIntersectsAABB(const ray& r, const AABB& b, vec3& vecIntersection)
{
	float tmin = 0;
	float tmax = b.Size().LengthSqr();	// It's a ray so make tmax effectively infinite.
	if (tmax < 1)
		tmax = 100;
	float flDistTbox = (r.m_pos - b.Center()).LengthSqr();
	if (flDistTbox < 1)
		flDistTbox = 100;
	tmax *= flDistTbox * 100;

	if (!ClipRay(b.m_mins.x, b.m_maxs.x, r.m_pos.x, r.m_dir.x, tmin, tmax))
		return false;

	if (!ClipRay(b.m_mins.y, b.m_maxs.y, r.m_pos.y, r.m_dir.y, tmin, tmax))
		return false;

	if (!ClipRay(b.m_mins.z, b.m_maxs.z, r.m_pos.z, r.m_dir.z, tmin, tmax))
		return false;

	vecIntersection = r.m_pos + r.m_dir * tmin;

	return true;
}
Exemplo n.º 7
0
Arquivo: ao.cpp Projeto: 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.
}