//-----------------------------------------------------------------------------
// Purpose: Replaces any missing textures with the default texture.
// Input  : pError - 
//-----------------------------------------------------------------------------
static void FixInvalidTexture(MapError *pError)
{
	CMapSolid *pSolid = (CMapSolid *)pError->pObjects[0];

	int nFaces = pSolid->GetFaceCount();
	for (int i = 0; i < nFaces; i++)
	{
		CMapFace *pFace = pSolid->GetFace(i);
		if (pFace != NULL)
		{
			IEditorTexture *pTex = pFace->GetTexture();
			if (pTex != NULL)
			{
				if (pTex->IsDummy())
				{
					pFace->SetTexture(GetDefaultTextureName());
				}
			}
		}
	}
}
Example #2
0
void CSSolid::ToMapSolid(CMapSolid *p)
{
	// so we can pass NULL (default) or another solid (to copy):
	CMapSolid *pSolid;
	if (p)
	{
		pSolid = p;
	}
	else
	{
		pSolid = m_pMapSolid;
	}

	pSolid->SetFaceCount(0);

	for (int i = 0; i < m_nFaces; i++)
	{
		CSSFace &face = m_Faces[i];
		CMapFace SolidFace;

		//
		// Copy original texture information and face ID back.
		//
		memcpy(&SolidFace.texture, &face.texture, sizeof(TEXTURE));
		SolidFace.SetTexture(SolidFace.texture.texture);
		SolidFace.SetFaceID(face.m_nFaceID);

		//
		// Create face from new points.
		//
		Vector *pts = CreatePointList(face);
		if (pts)
		{
			SolidFace.CreateFace(pts, face.nEdges);

			//
			// Vertex manipulation; the face orientation may have changed. If one of the texture axes is now
			// perpendicular to the face, recalculate the texture axes using the default alignment (world or face).
			// Ideally we would transform the texture axes so that their orientation relative to the face is preserved.
			// By reinitializing the axes we risk having the axes rotate unpredictably.
			//
			if (!SolidFace.IsTextureAxisValid())
			{
				SolidFace.InitializeTextureAxes(Options.GetTextureAlignment(), INIT_TEXTURE_AXES | INIT_TEXTURE_FORCE);
			}
				
			// Attempt to update the displacement - if there is one.
			if ( face.m_hDisp != EDITDISPHANDLE_INVALID )
			{
				EditDispHandle_t hDisp = EditDispMgr()->Create();
				CMapDisp *pSolidDisp = EditDispMgr()->GetDisp( hDisp );
				CMapDisp *pDisp = EditDispMgr()->GetDisp( face.m_hDisp );
				pSolidDisp->CopyFrom( pDisp, false );
				int iStart = pSolidDisp->GetSurfPointStartIndex();
				pSolidDisp->SetSurfPointStartIndex( (iStart+3)%4 );
				pSolidDisp->InitDispSurfaceData( &SolidFace, false );
				pSolidDisp->Create();
				SolidFace.SetDisp( hDisp );
			}

			pSolid->AddFace(&SolidFace);

			delete[] pts;
		}
	}

	pSolid->PostUpdate(Notify_Changed);
}
//-----------------------------------------------------------------------------
// Purpose: Applies dialog data to the list of selected faces.
// Input  : *pOnlyFace - 
//			bAll - 
//-----------------------------------------------------------------------------
void CFaceEditMaterialPage::Apply( CMapFace *pOnlyFace, int flags )
{
	int			i;
	CString		str;
	float		fshiftX = NOT_INIT;
	float		fshiftY = NOT_INIT;
	float		fscaleX = NOT_INIT;
	float		fscaleY = NOT_INIT;
	float		frotate = NOT_INIT;
	int			material = NOT_INIT;
	int			nLightmapScale = NOT_INIT;
	IEditorTexture	*pTex = m_TexturePic.GetTexture();

	//
	// Get numeric data.
	//
	if (flags & FACE_APPLY_MAPPING)
	{
		TransferToFloat( &m_shiftX, fshiftX );
		TransferToFloat( &m_shiftY, fshiftY );
		TransferToFloat( &m_scaleX, fscaleX );
		TransferToFloat( &m_scaleY, fscaleY );
		TransferToFloat( &m_rotate, frotate );
	}

	if (flags & FACE_APPLY_LIGHTMAP_SCALE)
	{
		TransferToInteger( &m_cLightmapScale, nLightmapScale );
	}

	if ( !pOnlyFace )
	{
		GetHistory()->MarkUndoPosition( NULL, "Apply Face Attributes" );

		// make sure we apply everything in this case.
		flags |= FACE_APPLY_ALL;

		// Keep the solids that we are about to change.
		// In the pOnlyFace case we do the Keep before calling ClickFace. Why?
		CUtlVector<CMapSolid *> kept;
		CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
		for( i = 0; i < pSheet->GetFaceListCount(); i++ )
		{
			CMapSolid *pSolid = pSheet->GetFaceListDataSolid( i );
			if ( kept.Find( pSolid ) == -1 )
			{
				GetHistory()->Keep( pSolid );
				kept.AddToTail( pSolid );
			}
		}
	}
		
	//
	// Run thru stored faces & apply.
	//
	CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
	int faceCount = pSheet->GetFaceListCount();
	for( i = 0; i < faceCount || pOnlyFace; i++ )
	{
		CMapFace *pFace;
		if( pOnlyFace )
		{
			pFace = pOnlyFace;
		}
		else
		{
			pFace = pSheet->GetFaceListDataFace( i );
		}

		//
		// Get values for texture shift, scale, rotate, and material.
		//
		if ((flags & FACE_APPLY_MAPPING) && (!(flags & FACE_APPLY_ALIGN_EDGE)))
		{
			if ( fshiftX != NOT_INIT )
			{
				pFace->texture.UAxis[3] = fshiftX;
			}

			if ( fshiftY != NOT_INIT )
			{
				pFace->texture.VAxis[3] = fshiftY;
			}

			if ( fscaleX != NOT_INIT )
			{
				pFace->texture.scale[0] = fscaleX;
			}
			
			if ( fscaleY != NOT_INIT )
			{
				pFace->texture.scale[1] = fscaleY;
			}

			if ( frotate != NOT_INIT )
			{
				pFace->RotateTextureAxes( frotate - pFace->texture.rotate );
				pFace->texture.rotate = frotate;
			}
		}

		if (flags & FACE_APPLY_CONTENTS_DATA)
		{
			if ( material != NOT_INIT )
			{
				pFace->texture.material = material;
			}
		}

		if (flags & FACE_APPLY_LIGHTMAP_SCALE)
		{
			if (nLightmapScale != NOT_INIT)
			{
				pFace->texture.nLightmapScale = max( nLightmapScale, 1 );
			}
		}

		//
		// Update the texture and recalculate texture coordinates.
		//
		if ((flags & FACE_APPLY_MATERIAL) && (pTex != NULL))
		{
			char szCurrentTexName[MAX_PATH];
			char szNewTexName[MAX_PATH];

			pFace->GetTextureName( szCurrentTexName );
			pTex->GetShortName( szNewTexName );

			if( stricmp( szCurrentTexName, szNewTexName ) != 0 )
			{
				pFace->SetTexture( szNewTexName );
			}
		}

		//
		// Copy texture coordinate system.
		//
		if ((flags & FACE_APPLY_ALIGN_EDGE) && (faceCount >= 1))
		{
			CopyTCoordSystem( pSheet->GetFaceListDataFace( faceCount - 1 ), pFace );
		}

		//
		// Recalculate texture coordinates.
		//
		pFace->CalcTextureCoords();

		//
		// Update the face flags.
		//
		if (flags & FACE_APPLY_CONTENTS_DATA)
		{
			//
			// Copy the bits from this face into our variables.
			//
			m_FaceContents = pFace->texture.q2contents;
			m_FaceSurface = pFace->texture.q2surface;

			//
			// Update our variables based on the state of the checkboxes.
			//
			for( int nItem = 0; nItem < sizeof( FaceAttributes ) / sizeof( FaceAttributes[0] ); nItem++ )
			{
				CButton *pButton = ( CButton* )GetDlgItem( FaceAttributes[nItem].uControlID );
				if( pButton != NULL )
				{
					int nSet = pButton->GetCheck();

					if (nSet == 0)
					{
						*FaceAttributes[nItem].puAttribute &= ~FaceAttributes[nItem].uFlag;
					}
					else if (nSet == 1)
					{
						*FaceAttributes[nItem].puAttribute |= FaceAttributes[nItem].uFlag;
					}
				}	
			}

			//
			// Copy our variables back into this face.
			//
			pFace->texture.q2contents = m_FaceContents;
			pFace->texture.q2surface = m_FaceSurface;
		}

		if( pOnlyFace )
		{
			break;
		}
	}

	CMapDoc::GetActiveMapDoc()->SetModifiedFlag();
}