Example #1
0
void Model::loadObj(QFile &file)
{
    // 1e9 = 1*10^9 = 1,000,000,000
    QVector3D boundsMin( 1e9, 1e9, 1e9);
    QVector3D boundsMax(-1e9,-1e9,-1e9);

    QTextStream in(&file);
    while (!in.atEnd()) {
        QString input = in.readLine();
        // # means comment
        if (input.isEmpty() || input[0] == '#')
            continue;

        QTextStream ts(&input);
        QString id;
        ts >> id;
        //---------------  v = List of vertices with (x,y,z[,w]) corrdinates. -----------------
        if (id == "v") {
            QVector3D p;
            for (int i = 0; i < 3; ++i) {
                ts >> p[i];
                boundsMin[i] = qMin(boundsMin[i], p[i]);
                boundsMax[i] = qMax(boundsMax[i], p[i]);
            }
            m_vertices << p;

        //--------------- f = Face definitions -----------------
        } else if (id == "f" || id == "fo") {
Example #2
0
Model::Model(const QString &filePath)
    : m_fileName(QFileInfo(filePath).fileName())
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly))
        return;

    QVector3D boundsMin( 1e9, 1e9, 1e9);
    QVector3D boundsMax(-1e9,-1e9,-1e9);

    QTextStream in(&file);
    while (!in.atEnd()) {
        QString input = in.readLine();
        if (input.isEmpty() || input[0] == '#')
            continue;

        QTextStream ts(&input);
        QString id;
        ts >> id;
        if (id == "v") {
            QVector3D p;
            for (int i = 0; i < 3; ++i) {
                ts >> ((float *)&p)[i];
                ((float *)&boundsMin)[i] = qMin(((float *)&boundsMin)[i], ((float *)&p)[i]);
                ((float *)&boundsMax)[i] = qMax(((float *)&boundsMax)[i], ((float *)&p)[i]);
            }
            m_points << p;
        } else if (id == "f" || id == "fo") {
/*
================
R_SurfaceToTextureAxis

Calculates two axis for the surface such that a point dotted against
the axis will give a 0.0 to 1.0 range in S and T when inside the gui surface
================
*/
void R_SurfaceToTextureAxis( const srfTriangles_t* tri, idVec3& origin, idVec3 axis[3] )
{
	// find the bounds of the texture
	idVec2 boundsMin( 999999.0f, 999999.0f );
	idVec2 boundsMax( -999999.0f, -999999.0f );
	for( int i = 0 ; i < tri->numVerts ; i++ )
	{
		const idVec2 uv = tri->verts[i].GetTexCoord();
		boundsMin.x = Min( uv.x, boundsMin.x );
		boundsMax.x = Max( uv.x, boundsMax.x );
		boundsMin.y = Min( uv.y, boundsMin.y );
		boundsMax.y = Max( uv.y, boundsMax.y );
	}
	
	// use the floor of the midpoint as the origin of the
	// surface, which will prevent a slight misalignment
	// from throwing it an entire cycle off
	const idVec2 boundsOrg( floor( ( boundsMin.x + boundsMax.x ) * 0.5f ), floor( ( boundsMin.y + boundsMax.y ) * 0.5f ) );
	
	// determine the world S and T vectors from the first drawSurf triangle
	
	// RB: added check wether GPU skinning is available at all
	const idJointMat* joints = ( tri->staticModelWithJoints != NULL && r_useGPUSkinning.GetBool() && glConfig.gpuSkinningAvailable ) ? tri->staticModelWithJoints->jointsInverted : NULL;
	// RB end
	
	const idVec3 aXYZ = idDrawVert::GetSkinnedDrawVertPosition( tri->verts[ tri->indexes[0] ], joints );
	const idVec3 bXYZ = idDrawVert::GetSkinnedDrawVertPosition( tri->verts[ tri->indexes[1] ], joints );
	const idVec3 cXYZ = idDrawVert::GetSkinnedDrawVertPosition( tri->verts[ tri->indexes[2] ], joints );
	
	const idVec2 aST = tri->verts[ tri->indexes[0] ].GetTexCoord();
	const idVec2 bST = tri->verts[ tri->indexes[1] ].GetTexCoord();
	const idVec2 cST = tri->verts[ tri->indexes[2] ].GetTexCoord();
	
	float d0[5];
	d0[0] = bXYZ[0] - aXYZ[0];
	d0[1] = bXYZ[1] - aXYZ[1];
	d0[2] = bXYZ[2] - aXYZ[2];
	d0[3] = bST.x - aST.x;
	d0[4] = bST.y - aST.y;
	
	float d1[5];
	d1[0] = cXYZ[0] - aXYZ[0];
	d1[1] = cXYZ[1] - aXYZ[1];
	d1[2] = cXYZ[2] - aXYZ[2];
	d1[3] = cST.x - aST.x;
	d1[4] = cST.y - aST.y;
	
	const float area = d0[3] * d1[4] - d0[4] * d1[3];
	if( area == 0.0f )
	{
		axis[0].Zero();
		axis[1].Zero();
		axis[2].Zero();
		return;	// degenerate
	}
	const float inva = 1.0f / area;
	
	axis[0][0] = ( d0[0] * d1[4] - d0[4] * d1[0] ) * inva;
	axis[0][1] = ( d0[1] * d1[4] - d0[4] * d1[1] ) * inva;
	axis[0][2] = ( d0[2] * d1[4] - d0[4] * d1[2] ) * inva;
	
	axis[1][0] = ( d0[3] * d1[0] - d0[0] * d1[3] ) * inva;
	axis[1][1] = ( d0[3] * d1[1] - d0[1] * d1[3] ) * inva;
	axis[1][2] = ( d0[3] * d1[2] - d0[2] * d1[3] ) * inva;
	
	idPlane plane;
	plane.FromPoints( aXYZ, bXYZ, cXYZ );
	axis[2][0] = plane[0];
	axis[2][1] = plane[1];
	axis[2][2] = plane[2];
	
	// take point 0 and project the vectors to the texture origin
	VectorMA( aXYZ, boundsOrg.x - aST.x, axis[0], origin );
	VectorMA( origin, boundsOrg.y - aST.y, axis[1], origin );
}
Example #4
0
void LightList::QueueDraw(Renderer& rRenderer, const Sky& rSky, const Camera& rCamera, const float sceneDepthMin, const float sceneDepthMax,
	RdrLightingMethod lightingMethod, RdrLightResources* pOutResources)
{
	Camera lightCamera;
	int curShadowMapIndex = 0;
	int curShadowCubeMapIndex = 0;
	int shadowMapsThisFrame = 0;

	// Update shadow casting lights and the global light constants
	// todo: Choose shadow lights based on location and dynamic object movement
	GlobalLightData* pGlobalLights = (GlobalLightData*)RdrFrameMem::AllocAligned(sizeof(GlobalLightData), 16);

	// Temporarily add sky light to the light list.
	m_directionalLights.push(rSky.GetSunLight());

	for (uint i = 0, count = m_directionalLights.size(); i < count; ++i)
	{
		DirectionalLight& rDirLight = m_directionalLights[i];
		int remainingShadowMaps = MAX_SHADOW_MAPS - curShadowMapIndex - 1;
		const int kNumCascades = 4;
		if (remainingShadowMaps >= kNumCascades)
		{
			// Directional lights always change because they're based on camera position/rotation
			rDirLight.shadowMapIndex = curShadowMapIndex;

			Rect viewport(0.f, 0.f, (float)s_shadowMapSize, (float)s_shadowMapSize);
			float zMin = sceneDepthMin;
			float zMax = sceneDepthMax;
			float zDiff = (zMax - zMin);

			float nearDepth = zMin;
			float lamda = rSky.GetPssmLambda();

			for (int iPartition = 0; iPartition < kNumCascades; ++iPartition)
			{
				float zUni = zMin + (zDiff / kNumCascades) * (iPartition + 1);
				float zLog = zMin * powf(zMax / zMin, (iPartition + 1) / (float)kNumCascades);
				float farDepth = lamda * zLog + (1.f - lamda) * zUni;

				Vec3 center = rCamera.GetPosition() + rCamera.GetDirection() * ((farDepth + nearDepth) * 0.5f);
				Matrix44 lightViewMtx = getLightViewMatrix(center, rDirLight.direction);

				Quad nearQuad = rCamera.GetFrustumQuad(nearDepth);
				QuadTransform(nearQuad, lightViewMtx);

				Quad farQuad = rCamera.GetFrustumQuad(farDepth);
				QuadTransform(farQuad, lightViewMtx);

				Vec3 boundsMin(FLT_MAX, FLT_MAX, FLT_MAX);
				Vec3 boundsMax(-FLT_MAX, -FLT_MAX, -FLT_MAX);
				accumQuadMinMax(nearQuad, boundsMin, boundsMax);
				accumQuadMinMax(farQuad, boundsMin, boundsMax);

				float height = (boundsMax.y - boundsMin.y);
				float width = (boundsMax.x - boundsMin.x);
				lightCamera.SetAsOrtho(center, rDirLight.direction, std::max(width, height), -500.f, 500.f);

				rRenderer.QueueShadowMapPass(lightCamera, m_shadowMapDepthViews[curShadowMapIndex], viewport);

				Matrix44 mtxView;
				Matrix44 mtxProj;
				lightCamera.GetMatrices(mtxView, mtxProj);
				pGlobalLights->shadowData[curShadowMapIndex].mtxViewProj = Matrix44Multiply(mtxView, mtxProj);
				pGlobalLights->shadowData[curShadowMapIndex].mtxViewProj = Matrix44Transpose(pGlobalLights->shadowData[curShadowMapIndex].mtxViewProj);
				pGlobalLights->shadowData[curShadowMapIndex].partitionEndZ = (iPartition == kNumCascades - 1) ? FLT_MAX : farDepth;

				++shadowMapsThisFrame;
				++curShadowMapIndex;
				nearDepth = farDepth;
			}
		}
		else
		{
			rDirLight.shadowMapIndex = -1;
		}
	}

	for (uint i = 0, count = m_spotLights.size(); i < count; ++i)
	{
		SpotLight& rSpotLight = m_spotLights[i];
		int remainingShadowMaps = MAX_SHADOW_MAPS - curShadowMapIndex - 1;
		if (remainingShadowMaps)
		{
			Matrix44 mtxView;
			Matrix44 mtxProj;

			float angle = rSpotLight.outerConeAngle + Maths::DegToRad(5.f);
			lightCamera.SetAsPerspective(rSpotLight.position, rSpotLight.direction, angle * 2.f, 1.f, 0.1f, 1000.f);
			lightCamera.GetMatrices(mtxView, mtxProj);

			pGlobalLights->shadowData[curShadowMapIndex].mtxViewProj = Matrix44Multiply(mtxView, mtxProj);
			pGlobalLights->shadowData[curShadowMapIndex].mtxViewProj = Matrix44Transpose(pGlobalLights->shadowData[curShadowMapIndex].mtxViewProj);

			Rect viewport(0.f, 0.f, (float)s_shadowMapSize, (float)s_shadowMapSize);
			rRenderer.QueueShadowMapPass(lightCamera, m_shadowMapDepthViews[curShadowMapIndex], viewport);

			rSpotLight.shadowMapIndex = curShadowMapIndex;
			++shadowMapsThisFrame;
			++curShadowMapIndex;
		}
		else
		{
			rSpotLight.shadowMapIndex = -1;
		}
	}

	for (uint i = 0, count = m_pointLights.size(); i < count; ++i)
	{
		PointLight& rPointLight = m_pointLights[i];
		int remainingShadowCubeMaps = MAX_SHADOW_CUBEMAPS - curShadowCubeMapIndex - 1;
		if (remainingShadowCubeMaps)
		{
			rPointLight.shadowMapIndex = curShadowCubeMapIndex + MAX_SHADOW_MAPS;

			Rect viewport(0.f, 0.f, (float)s_shadowCubeMapSize, (float)s_shadowCubeMapSize);
#if USE_SINGLEPASS_SHADOW_CUBEMAP
			rRenderer.QueueShadowCubeMapPass(rPointLight, m_shadowCubeMapDepthViews[curShadowCubeMapIndex], viewport);
#else
			for (uint face = 0; face < 6; ++face)
			{
				lightCamera.SetAsCubemapFace(light.position, (CubemapFace)face, 0.1f, light.radius * 2.f);
				rRenderer.QueueShadowMapPass(lightCamera, m_shadowCubeMapDepthViews[curShadowCubeMapIndex * 6 + face], viewport);
			}
#endif
			++shadowMapsThisFrame;
			++curShadowCubeMapIndex;
		}
		else
		{
			rPointLight.shadowMapIndex = -1;
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// Apply resource updates
	RdrResourceCommandList* pResCommandList = rRenderer.GetActionCommandList();

	// Update spot lights
	SpotLight* pSpotLights = (SpotLight*)RdrFrameMem::Alloc(sizeof(SpotLight) * m_spotLights.size());
	memcpy(pSpotLights, m_spotLights.getData(), sizeof(SpotLight) * m_spotLights.size());
	if (!m_hSpotLightListRes)
		m_hSpotLightListRes = pResCommandList->CreateStructuredBuffer(pSpotLights, m_spotLights.capacity(), sizeof(SpotLight), RdrResourceUsage::Dynamic);
	else
		pResCommandList->UpdateBuffer(m_hSpotLightListRes, pSpotLights, sizeof(SpotLight) * m_spotLights.size());

	// Update point lights
	PointLight* pPointLights = (PointLight*)RdrFrameMem::Alloc(sizeof(PointLight) * m_pointLights.size());
	memcpy(pPointLights, m_pointLights.getData(), sizeof(PointLight) * m_pointLights.size());
	if (!m_hPointLightListRes)
		m_hPointLightListRes = pResCommandList->CreateStructuredBuffer(pPointLights, m_pointLights.capacity(), sizeof(PointLight), RdrResourceUsage::Dynamic);
	else
		pResCommandList->UpdateBuffer(m_hPointLightListRes, pPointLights, sizeof(PointLight) * m_pointLights.size());

	// Update environment lights
	EnvironmentLight* pEnvironmentLights = (EnvironmentLight*)RdrFrameMem::Alloc(sizeof(EnvironmentLight) * m_environmentLights.size());
	memcpy(pEnvironmentLights, m_environmentLights.getData(), sizeof(EnvironmentLight) * m_environmentLights.size());
	if (!m_hEnvironmentLightListRes)
		m_hEnvironmentLightListRes = pResCommandList->CreateStructuredBuffer(pEnvironmentLights, m_environmentLights.capacity(), sizeof(EnvironmentLight), RdrResourceUsage::Dynamic);
	else
		pResCommandList->UpdateBuffer(m_hEnvironmentLightListRes, pEnvironmentLights, sizeof(EnvironmentLight) * m_environmentLights.size());

	// Light culling
	if (lightingMethod == RdrLightingMethod::Clustered)
	{
		QueueClusteredLightCulling(rRenderer, rCamera);
	}
	else
	{
		QueueTiledLightCulling(rRenderer, rCamera);
	}

	// Update global lights constant buffer last so the light culling data is up to date.
	pGlobalLights->numDirectionalLights = m_directionalLights.size();
	pGlobalLights->globalEnvironmentLight = m_globalEnvironmentLight;
	pGlobalLights->clusterTileSize = m_clusteredLightData.clusterTileSize;
	memcpy(pGlobalLights->directionalLights, m_directionalLights.getData(), sizeof(DirectionalLight) * pGlobalLights->numDirectionalLights);
	m_hGlobalLightsCb = pResCommandList->CreateUpdateConstantBuffer(m_hGlobalLightsCb,
		pGlobalLights, sizeof(GlobalLightData), RdrCpuAccessFlags::Write, RdrResourceUsage::Dynamic);

	// Remove sky light.
	m_directionalLights.pop();


	// Fill out resource params
	pOutResources->hGlobalLightsCb = m_hGlobalLightsCb;
	pOutResources->hSpotLightListRes = m_hSpotLightListRes;
	pOutResources->hPointLightListRes = m_hPointLightListRes;
	pOutResources->hEnvironmentLightListRes = m_hEnvironmentLightListRes;
	pOutResources->hShadowCubeMapTexArray = m_hShadowCubeMapTexArray;
	pOutResources->hShadowMapTexArray = m_hShadowMapTexArray;
	pOutResources->hEnvironmentMapTexArray = m_hEnvironmentMapTexArray;
	pOutResources->hLightIndicesRes = (lightingMethod == RdrLightingMethod::Clustered) ? 
		m_clusteredLightData.hLightIndices : m_tiledLightData.hLightIndices;
}
Example #5
0
void Model::loadFile(QString filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly))
        return;

    //如下两个变量存放模型的边界
    Point3d boundsMin( 1e9, 1e9, 1e9);
    Point3d boundsMax(-1e9,-1e9,-1e9);

    //读取obj格式的文件
    QTextStream in(&file);
    //now begin to read the verters

    Point3d pi;
    float currentZ = 0.0;
    float currentX = 0.0;
    float currentY = 0.0;
    QRegExp regZ("[\w\d\s]*Z([0-9\.]*[0-9]*)");
    QRegExp regL(";LAYER: *([0-9]*)");
    QRegExp regXY("G1 [\w\d\s]* *X([0-9\.]*[0-9]*) *Y([0-9\.]*[0-9]*)");
    bool isZ = false;
    bool isIn = false;
    while(!in.atEnd())
    {
        QString current_str = in.readLine();
        if(current_str.contains(regXY))
        {
            currentX = regXY.cap(1).toFloat();
            currentY = regXY.cap(2).toFloat();
            boundsMin.x = qMin(boundsMin.x,currentX);
            boundsMax.x = qMax(boundsMax.x, currentX);
            boundsMin.y = qMin(boundsMin.y,currentY);
            boundsMax.y = qMax(boundsMax.y, currentY);
            boundsMin.z = qMin(boundsMin.z,currentZ);
            boundsMax.z = qMax(boundsMax.z, currentZ);
             qDebug()<< QObject::tr("Xs=%1").arg(currentX);
            pi = Point3d(currentX,currentY,currentZ);
            m_points.push_back(pi);
        }
        if(current_str.contains(regL))
        {
            if((regL.cap(1))=="0")
                isIn = false;
            else
                isIn = true;

            isZ = true;

        }
        if(current_str.contains(regZ)&&(isZ))
        {

            isZ = false;
            QString str_Z = regZ.cap(1);
            currentZ = str_Z.toFloat();
        }

    }
    const Point3d bounds = boundsMax - boundsMin;
    const qreal scale = 100 / qMax(bounds.x, qMax(bounds.y, bounds.z));
        for(int j=0;j<m_points.size();j++)
        {
            m_points[j] = (m_points[j] - (boundsMin + bounds * 0.5)) * scale;
            qDebug()<< QObject::tr("X=%1").arg(m_points[j].x);
        }
}