int CreateBrushVersionOfWorldVertexTransitionMaterial( int originalTexInfo ) { // Don't make cubemap tex infos for nodes if ( originalTexInfo == TEXINFO_NODE ) return originalTexInfo; texinfo_t *pTexInfo = &texinfo[originalTexInfo]; dtexdata_t *pTexData = GetTexData( pTexInfo->texdata ); const char *pOriginalMaterialName = TexDataStringTable_GetString( pTexData->nameStringTableID ); // Get out of here if the originalTexInfo is already a patched wvt material if ( Q_stristr( pOriginalMaterialName, "_wvt_patch" ) ) return originalTexInfo; char patchedMaterialName[1024]; GeneratePatchedMaterialName( pOriginalMaterialName, patchedMaterialName, 1024 ); // Warning( "GeneratePatchedMaterialName: %s %s\n", pMaterialName, patchedMaterialName ); // Make sure the texdata doesn't already exist. int nTexDataID = FindTexData( patchedMaterialName ); bool bHasTexData = (nTexDataID != -1); if( !bHasTexData ) { // Create the new vmt material file CreateWorldVertexTransitionPatchedMaterial( pOriginalMaterialName, patchedMaterialName ); // Make a new texdata nTexDataID = AddCloneTexData( pTexData, patchedMaterialName ); } Assert( nTexDataID != -1 ); texinfo_t newTexInfo; newTexInfo = *pTexInfo; newTexInfo.texdata = nTexDataID; int nTexInfoID = -1; // See if we need to make a new texinfo bool bHasTexInfo = false; if( bHasTexData ) { nTexInfoID = FindTexInfo( newTexInfo ); bHasTexInfo = (nTexInfoID != -1); } // Make a new texinfo if we need to. if( !bHasTexInfo ) { nTexInfoID = texinfo.AddToTail( newTexInfo ); } Assert( nTexInfoID != -1 ); return nTexInfoID; }
//----------------------------------------------------------------------------- // Purpose: Finds or adds a texdata for the specified name // Input : *pName - texture name // Output : int index into dtexdata array //----------------------------------------------------------------------------- int FindOrCreateTexData( const char *pName_ ) { char *pName = ( char * )_alloca( strlen( pName_ ) + 1 ); strcpy( pName, pName_ ); int nOutput = FindTexData( pName ); if ( nOutput >= 0 ) return nOutput; // Didn't find it, add a new one nOutput = numtexdata; if ( numtexdata >= MAX_MAP_TEXDATA ) { Error( "Too many unique texture mappings, max = %d\n", MAX_MAP_TEXDATA ); } dtexdata_t *pTexData = GetTexData( nOutput ); numtexdata++; // Save the name of the material. pTexData->nameStringTableID = TexDataStringTable_AddOrFindString( pName ); // Get the width, height, view_width, view_height, and reflectivity from the material system. bool bFound; MaterialSystemMaterial_t matID = FindOriginalMaterial( pName, &bFound ); if ( matID == MATERIAL_NOT_FOUND || (!bFound) ) { qprintf( "WARNING: material not found: \"%s\"\n", pName ); return nOutput; } GetMaterialDimensions( matID, &pTexData->width, &pTexData->height ); pTexData->view_width = pTexData->width; // undone: what is this? pTexData->view_height = pTexData->height; // undone: what is this? GetMaterialReflectivity( matID, pTexData->reflectivity.Base() ); g_SurfaceProperties[nOutput] = GetSurfaceProperties( matID, pName ); #if 0 Msg( "reflectivity: %f %f %f\n", pTexData->reflectivity[0], pTexData->reflectivity[1], pTexData->reflectivity[2] ); #endif return nOutput; }
//----------------------------------------------------------------------------- // Create a VMT to override the specified texinfo which references the cubemap entity at the specified origin. // Returns the index of the new (or preexisting) texinfo referencing that VMT. // // Also adds the new cubemap VTF filename to s_DefaultCubemapNames so it can copy the // default (skybox) cubemap into this file so the cubemap doesn't have the pink checkerboard at // runtime before they run buildcubemaps. //----------------------------------------------------------------------------- static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3] ) { // Don't make cubemap tex infos for nodes if ( originalTexInfo == TEXINFO_NODE ) return originalTexInfo; texinfo_t *pTexInfo = &texinfo[originalTexInfo]; dtexdata_t *pTexData = GetTexData( pTexInfo->texdata ); const char *pMaterialName = TexDataStringTable_GetString( pTexData->nameStringTableID ); if ( g_IsCubemapTexData[pTexInfo->texdata] ) { Warning("Multiple references for cubemap on texture %s!!!\n", pMaterialName ); return originalTexInfo; } // Get out of here if the originalTexInfo is already a generated material for this position. char pStringToSearchFor[512]; Q_snprintf( pStringToSearchFor, 512, "_%d_%d_%d", origin[0], origin[1], origin[2] ); if ( Q_stristr( pMaterialName, pStringToSearchFor ) ) return originalTexInfo; // Package up information needed to generate patch names PatchInfo_t info; info.m_pMapName = mapbase; info.m_pOrigin[0] = origin[0]; info.m_pOrigin[1] = origin[1]; info.m_pOrigin[2] = origin[2]; // Generate the name of the patched material char pGeneratedTexDataName[1024]; GeneratePatchedName( pMaterialName, info, true, pGeneratedTexDataName, 1024 ); // Make sure the texdata doesn't already exist. int nTexDataID = FindTexData( pGeneratedTexDataName ); bool bHasTexData = (nTexDataID != -1); if( !bHasTexData ) { // Generate the new "$envmap" texture name. char pTextureName[1024]; GeneratePatchedName( "c", info, false, pTextureName, 1024 ); // Hook the texture into the material and all dependent materials // but if no hooking was necessary, exit out if ( !PatchEnvmapForMaterialAndDependents( pMaterialName, info, pTextureName ) ) return originalTexInfo; // Store off the name of the cubemap that we need to create since we successfully patched char pFileName[1024]; int nLen = Q_snprintf( pFileName, 1024, "materials/%s.vtf", pTextureName ); int id = s_DefaultCubemapNames.AddToTail(); s_DefaultCubemapNames[id] = new char[ nLen + 1 ]; strcpy( s_DefaultCubemapNames[id], pFileName ); // Make a new texdata nTexDataID = AddCloneTexData( pTexData, pGeneratedTexDataName ); g_IsCubemapTexData[nTexDataID] = true; } Assert( nTexDataID != -1 ); texinfo_t newTexInfo; newTexInfo = *pTexInfo; newTexInfo.texdata = nTexDataID; int nTexInfoID = -1; // See if we need to make a new texinfo bool bHasTexInfo = false; if( bHasTexData ) { nTexInfoID = FindTexInfo( newTexInfo ); bHasTexInfo = (nTexInfoID != -1); } // Make a new texinfo if we need to. if( !bHasTexInfo ) { nTexInfoID = texinfo.AddToTail( newTexInfo ); } Assert( nTexInfoID != -1 ); return nTexInfoID; }
int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, const Vector& origin) { Vector vecs[2]; int sv, tv; vec_t ang, sinv, cosv; vec_t ns, nt; texinfo_t tx, *tc; int i, j, k; if (!bt->name[0]) return 0; memset (&tx, 0, sizeof(tx)); // HLTOOLS - add support for texture vectors stored in the map file if (g_nMapFileVersion < 220) { TextureAxisFromPlane(plane, vecs[0], vecs[1]); } if (!bt->textureWorldUnitsPerTexel[0]) bt->textureWorldUnitsPerTexel[0] = 1; if (!bt->textureWorldUnitsPerTexel[1]) bt->textureWorldUnitsPerTexel[1] = 1; if (g_nMapFileVersion < 220) { // rotate axis if (bt->rotate == 0) { sinv = 0 ; cosv = 1; } else if (bt->rotate == 90) { sinv = 1 ; cosv = 0; } else if (bt->rotate == 180) { sinv = 0 ; cosv = -1; } else if (bt->rotate == 270) { sinv = -1 ; cosv = 0; } else { ang = bt->rotate / 180 * M_PI; sinv = sin(ang); cosv = cos(ang); } if (vecs[0][0]) sv = 0; else if (vecs[0][1]) sv = 1; else sv = 2; if (vecs[1][0]) tv = 0; else if (vecs[1][1]) tv = 1; else tv = 2; for (i=0 ; i<2 ; i++) { ns = cosv * vecs[i][sv] - sinv * vecs[i][tv]; nt = sinv * vecs[i][sv] + cosv * vecs[i][tv]; vecs[i][sv] = ns; vecs[i][tv] = nt; } for (i=0 ; i<2 ; i++) { for (j=0 ; j<3 ; j++) { tx.textureVecsTexelsPerWorldUnits[i][j] = vecs[i][j] / bt->textureWorldUnitsPerTexel[i]; tx.lightmapVecsLuxelsPerWorldUnits[i][j] = tx.textureVecsTexelsPerWorldUnits[i][j] / 16.0f; } } } else { tx.textureVecsTexelsPerWorldUnits[0][0] = bt->UAxis[0] / bt->textureWorldUnitsPerTexel[0]; tx.textureVecsTexelsPerWorldUnits[0][1] = bt->UAxis[1] / bt->textureWorldUnitsPerTexel[0]; tx.textureVecsTexelsPerWorldUnits[0][2] = bt->UAxis[2] / bt->textureWorldUnitsPerTexel[0]; tx.textureVecsTexelsPerWorldUnits[1][0] = bt->VAxis[0] / bt->textureWorldUnitsPerTexel[1]; tx.textureVecsTexelsPerWorldUnits[1][1] = bt->VAxis[1] / bt->textureWorldUnitsPerTexel[1]; tx.textureVecsTexelsPerWorldUnits[1][2] = bt->VAxis[2] / bt->textureWorldUnitsPerTexel[1]; tx.lightmapVecsLuxelsPerWorldUnits[0][0] = bt->UAxis[0] / bt->lightmapWorldUnitsPerLuxel; tx.lightmapVecsLuxelsPerWorldUnits[0][1] = bt->UAxis[1] / bt->lightmapWorldUnitsPerLuxel; tx.lightmapVecsLuxelsPerWorldUnits[0][2] = bt->UAxis[2] / bt->lightmapWorldUnitsPerLuxel; tx.lightmapVecsLuxelsPerWorldUnits[1][0] = bt->VAxis[0] / bt->lightmapWorldUnitsPerLuxel; tx.lightmapVecsLuxelsPerWorldUnits[1][1] = bt->VAxis[1] / bt->lightmapWorldUnitsPerLuxel; tx.lightmapVecsLuxelsPerWorldUnits[1][2] = bt->VAxis[2] / bt->lightmapWorldUnitsPerLuxel; } tx.textureVecsTexelsPerWorldUnits[0][3] = bt->shift[0] + DOT_PRODUCT( origin, tx.textureVecsTexelsPerWorldUnits[0] ); tx.textureVecsTexelsPerWorldUnits[1][3] = bt->shift[1] + DOT_PRODUCT( origin, tx.textureVecsTexelsPerWorldUnits[1] ); tx.lightmapVecsLuxelsPerWorldUnits[0][3] = bt->shift[0] + DOT_PRODUCT( origin, tx.lightmapVecsLuxelsPerWorldUnits[0] ); tx.lightmapVecsLuxelsPerWorldUnits[1][3] = bt->shift[1] + DOT_PRODUCT( origin, tx.lightmapVecsLuxelsPerWorldUnits[1] ); tx.flags = bt->flags; // // find the texinfo // if ( numtexinfo >= MAX_MAP_TEXINFO ) { Error( "Map has too many texinfos, MAX_MAP_TEXINFO == %i\n", MAX_MAP_TEXINFO ); } tc = texinfo; tx.texdata = FindTexData( bt->name ); for (i=0 ; i<numtexinfo ; i++, tc++) { if (tc->flags != tx.flags) continue; bool skip = false; for (j=0 ; j<2 && !skip; j++) { if ( tc->texdata != tx.texdata ) { skip = true; break; } for (k=0 ; k<4 && !skip; k++) { if (tc->textureVecsTexelsPerWorldUnits[j][k] != tx.textureVecsTexelsPerWorldUnits[j][k]) { skip = true; break; } if( tc->lightmapVecsLuxelsPerWorldUnits[j][k] != tx.lightmapVecsLuxelsPerWorldUnits[j][k] ) { skip = true; break; } } } if ( skip ) { continue; } return i; } *tc = tx; if ( onlyents ) { Error( "FindOrCreateTexInfo: Tried to create new texinfo during -onlyents compile!\n" ); } numtexinfo++; return i; }