// /*============================================================================= * * Filename: VMatObj.cpp * Version: 1.0 * Date: 06/11/96 * Author: B.G. * * Description: implementation of editor material class * *===========================================================================*/ #include "stdafx.h" #include "Acp_base.h" #include "itf.h" #include "gmt.h" #include "IncMEC.h" #include "gli.h" #include "x:\cpa\main\inc\_editid.h" #include "inctex.h" #include "_interf.hpp" #include "GMatObj.hpp" #include "VMatObj.hpp" #include "TexObj.hpp" extern Material_Interface *gs_p_oMaterialInterface; extern FILE *g_xLogFile; //================================================================================= //================================================================================= //================================================================================= tdoEditorVisualMaterial::tdoEditorVisualMaterial( CPA_FileObject *_p_oOwnerFile, CString _csId, BOOL _bSectionAlreadyExists, ACP_tdxHandleOfMaterial _hTemplateVisualMaterial ) : CPA_SaveObject( gs_p_oMaterialInterface, //editor C_szVisualMaterialTypeName, //type E_ss_Responsible, //responsibility _p_oOwnerFile, //owner (there is none) FALSE, //available (char*)LPCTSTR(_p_oOwnerFile->GetCompletionPath(gs_p_oMaterialInterface, C_szFileReferencedNameKey)), //data path to complete the referenced section name m_vCallBackSaveVMT//callback ) { //tell the file object that an object exists for its section g_oCoherenceManager.m_fn_vAddALink(_p_oOwnerFile, this); ASSERT(_hTemplateVisualMaterial); //the editor object directly handles the engine object m_hVisualMaterial = _hTemplateVisualMaterial; SetAvailable(_hTemplateVisualMaterial ? TRUE : FALSE); // construct section name (hack: szSectionName is here as an anti-bug for ...Split... char szSectionName[SCR_CV_ui_Cfg_MaxLenName]; SCR_fn_v_RdL0_ComputeSectionName( szSectionName, (char*)LPCTSTR(_p_oOwnerFile->GetReferencedName(gs_p_oMaterialInterface, C_szFileReferencedNameKey)), GLI_C_SectionVisualMaterial, (char*)LPCTSTR(_csId) ); // section object SetSectionData(this); SetReferencedSectionName(szSectionName); // name if ( fn_eRename(_csId) != E_mc_None ) SetDefaultValidName(); fn_vUpdateSectionName(); if ( _bSectionAlreadyExists ) fn_vSectionSaved(); //the section is saved, and has no pending notification else fn_vSectionDeleted(); //the section does not exist, and has no pending nofitication if ( fn_bCanBeNotified() && !fn_bSectionExists() ) fn_vNotifySave(); if ( fn_bIsAvailable() ) { //to simplify edition, make all textures as animation components long lNbTextures = GLI_lGetMaterialNumberOfAnimatedTexture(m_hVisualMaterial); if ( !lNbTextures ) { unsigned long ulSaveType; GLI_xGetMaterialType(m_hVisualMaterial, &ulSaveType); //read the standard texture handle GLI_tdstTexture *p_stTexture; GLI_xGetMaterialTexture(m_hVisualMaterial, &p_stTexture); //and mark it as an animated texture as well if ( p_stTexture ) { GLI_vAddMaterialAnimatedTexture(m_hVisualMaterial, 0, p_stTexture, (float) (100.0 + ((double) rand() / RAND_MAX))); lNbTextures = 1; //tell the engine something changed with the animated textures GLI_xRefreshAnimatedTexture(m_hVisualMaterial); } GLI_xSetMaterialType(m_hVisualMaterial, ulSaveType); } for ( lNbTextures --; lNbTextures >= 0; lNbTextures -- ) //scan all the textures used by the material { float fDuration; GLI_tdstTexture *p_stTexture; GLI_vGetMaterialAnimatedTexture(m_hVisualMaterial, lNbTextures, &p_stTexture, &fDuration); //now lets create the editor texture objects, if necessary CPA_FileObject *p_oFileObject = NULL; //if we set the file object, this means we want to create a section, else the section alredy exists tdoEditorTexture *p_oEditorTexture = NULL; CString csName; if ( p_stTexture //if the texture object does not exist already for this engine data && !(p_oEditorTexture = (tdoEditorTexture *) gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(p_stTexture)) ) { SCR_tdst_Link_Value *p_stTextureEntry; char sz100BitmapName[100]; //try to find the texture when referenced as a section if ( p_stTextureEntry = SCR_fnp_st_Link_SearchValue(GLI_p_stGetLinkTableOfTextureSection(), (unsigned long) p_stTexture) ) { char *pszKey = SCR_M_p_sz_Link_GetKey(p_stTextureEntry); char szTextureFile[SCR_CV_ui_Cfg_MaxLenName], szTextureName[SCR_CV_ui_Cfg_MaxLenName]; //get the section name from the linktable entry SCR_fn_v_RdL0_SplitSectionName(pszKey, szTextureFile, NULL, szTextureName); //get the file object for this referenced path p_oFileObject = p_oGetFileObjectForCompletePath(szTextureFile); csName = szTextureName; //find it by name and owner p_oEditorTexture = (tdoEditorTexture *) gs_p_oMaterialInterface->GetBaseObject( csName, C_szTextureTypeName, p_oFileObject ); //since it is in the section link table, the object must exist, since the editor creates editor //objects for all the sections (loaded or not) at initialization... ASSERT(p_oEditorTexture); //the section was analyzed, but at some other point we might have created an editor object //for the same section with another handle: the valid handle is the current one, so tell //the texture section object to drop its current handle, and to update its referencing VMTs //as well, if relevant p_oEditorTexture->m_vReplaceHandle(p_stTexture); } else if ( p_stTextureEntry = SCR_fnp_st_Link_SearchValue(GLI_p_stGetLinkTableOfTexture(), (unsigned long) p_stTexture) ) { //the material references the bitmap directly strcpy(sz100BitmapName, SCR_M_p_sz_Link_GetKey(p_stTextureEntry) + SCR_M_ul_Link_GetAdditionalLong(p_stTextureEntry, 1)); } else //a valid texture handle and no linktable entry ? that is not well!!! { //get the name in the texture descriptor GLI_vGetTextureName(p_stTexture, sz100BitmapName); //output some warning message if ( gs_p_oMaterialInterface->m_bLoadWarningsAreEnabled() ) AfxMessageBox( CString("The texture ") + sz100BitmapName + "\nappears in more than one section, including " + szSectionName + "\nYou can continue your work, but you should solve this problem.", MB_OK ); if ( g_xLogFile ) { //and log the error in the log file CString csLogMessage("multiple bitmap reference: "); csLogMessage += szSectionName; csLogMessage += " -> "; csLogMessage += sz100BitmapName; fprintf(g_xLogFile, "%s\n", LPCTSTR(csLogMessage)); fflush(g_xLogFile); } } if ( !p_oEditorTexture ) //if the material references a bitmap directly (since no section was found for the texture...) { //determine the name of the texture file for the new texture section CString csFileObjectName = _p_oOwnerFile->GetReferencedName(gs_p_oMaterialInterface, C_szFileReferencedNameKey); csFileObjectName = csFileObjectName.Left(csFileObjectName.ReverseFind('.')) + tdoEditorTexture::m_csGetScriptExtension(); //get the associated file object p_oFileObject = p_oGetFileObjectForReferencedPath(csFileObjectName); //the section will be named from the texture it references, without the file extension csName = CString("TEX_") + fn_pszBaseName0(sz100BitmapName); csName = csName.Left(csName.ReverseFind('.')); //replace characters tha are fobidden in section names short wSpacePos; while ( (wSpacePos = csName.FindOneOf(" :^")) != -1 ) csName.SetAt(wSpacePos, '_'); //the section was not analysed: it does not exist //make sure we did not create at init such a texture section object that is not loaded yet... p_oEditorTexture = (tdoEditorTexture *) gs_p_oMaterialInterface->GetBaseObject( csName, C_szTextureTypeName, p_oFileObject ); if ( !p_oEditorTexture ) //we did not find a loaded texture section that references the same bitmap name { //try to find an editor texture section that has the correct bitmap name CPA_BaseObjectList *p_oList = gs_p_oMaterialInterface->GetBaseObjectList(C_szTextureTypeName); //scan the list of editor textures Position xPos = p_oList->GetHeadPosition(); while ( xPos ) { tdoEditorTexture *p_oCurrentTexture = (tdoEditorTexture *) p_oList->GetNext(xPos); if ( p_oCurrentTexture->fn_bIsAvailable() && !p_oCurrentTexture->m_csGetTextureName().CompareNoCase(sz100BitmapName) ) { //we found a loaded editor texture that has the same bitmap, however through a different handle //since the texture object references this texture bitmap, use it, whatever its name p_oEditorTexture = p_oCurrentTexture; break; } } } if ( p_oEditorTexture ) { if ( !(p_stTexture = p_oEditorTexture->m_hGetEngineTexture()) ) //the texture section we found is not loaded yet { //load it now p_oEditorTexture->m_vLoadAssociatedEngineTexture(); //and remember its handle p_stTexture = p_oEditorTexture->m_hGetEngineTexture(); } //we found a loaded editor texture for an existing section, which has a different handle: //we now use its handle instead of our current one, since ours does not come from a section... GLI_vModifyMaterialAnimatedTexture(m_hVisualMaterial, lNbTextures, p_stTexture, fDuration); if ( lNbTextures == 0 ) GLI_xSetMaterialTexture(m_hVisualMaterial, p_stTexture); } //since we reference a section now, we must force saving of the visual material to account for it fn_vNotifySave(); } } //a texture object is not yet associated with the referenced texture handle if ( !p_oEditorTexture ) //if the editor texture already exists p_oEditorTexture = new tdoEditorTexture( p_oFileObject, csName, FALSE, //the section does not exist p_stTexture ); //tell the cohemngr that the created editor texture is used by the visual material g_oCoherenceManager.m_fn_vAddALink(this, p_oEditorTexture); } //texture list loop } //the handle is valid } //================================================================================= //================================================================================= tdoEditorVisualMaterial::~tdoEditorVisualMaterial() { //remove myself totally from the coherence manager database if ( !fn_bSectionExists() ) g_oCoherenceManager.m_fn_vRemoveAllLinks(this, C_cLinkedAsChild); } //================================================================================ //================================================================================ BOOL tdoEditorVisualMaterial::m_bIsReferenced() { return g_oCoherenceManager.m_fn_iGetFatherCount(this) > 1; } /*================================================================================= //save a section of the form: {Material: Type([Gouraud|Flat]) AmbientColor(0.000000,0.000000,0.886275) DiffuseColor(1.000000,1.000000,0.960784) SpecularColor(1.000000,1.000000,0.960784,0.000000) Texture() } //=================================================================================*/ /*static*/ void tdoEditorVisualMaterial::m_vCallBackSaveVMT( SCR_tdst_File_Description *_p_stFile, char *_p_szSectionName, void *_p_vData, SCR_tde_Ntfy_Action _eAction ) { tdoEditorVisualMaterial *p_oEditorMaterial = (tdoEditorVisualMaterial *) _p_vData; if ( _eAction == SCR_EA_Ntfy_DeleteSection ) //now the section exists, if this was not the case p_oEditorMaterial->fn_vSectionDeleted(); //the section does not exist, and has no pending nofitication if ( _eAction != SCR_EA_Ntfy_AddSection && _eAction != SCR_EA_Ntfy_RebuildSection ) return; if ( _eAction == SCR_EA_Ntfy_AddSection ) { // go to end of file (we need all file directive to load this section) SCR_fn_v_SvL1_ToEndSection(_p_stFile); SCR_M_SvL0_SaveBlankLine (_p_stFile); } char szSectionName[SCR_CV_ui_Cfg_MaxLenName],szAction[SCR_CV_ui_Cfg_MaxLenName],szId[SCR_CV_ui_Cfg_MaxLenName]; // construct section name (hack: szSectionName is here as an anti-bug for ...Split... SCR_fn_v_RdL0_SplitSectionName(_p_szSectionName, szSectionName, szAction, szId); SCR_fn_v_RdL0_ComputeSectionName(szSectionName, NULL, szAction, szId); // save begin section for the game material SCR_M_SvL0_SaveBeginSection(_p_stFile, szSectionName, SCR_CC_C_Cfg_EOL); //get the handles we need ACP_tdxHandleOfMaterial hMaterialVisual = p_oEditorMaterial->m_hGetEngineMaterial(); //get the parameters we want to save unsigned long xMType; GEO_tdstColor stColor; long lSpecularExponent; //type GLI_xGetMaterialType(hMaterialVisual, &xMType); char *pszType; if ( xMType & GLI_C_lIsGouraud ) { if ( xMType & GLI_C_lIsNotLightAlphaSensitive ) //the material is not alpha sensitive if ( xMType & GLI_C_lIsNotGrided ) pszType = "Gouraud"; else pszType = "Transparent"; else pszType = "GouraudAlpha"; } else //the material is not gouraud-shaded pszType = "Flat"; SCR_M_SvL0_SaveEntry(_p_stFile, "Type", SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, pszType); //ambient color GLI_xGetMaterialAmbientCoef(hMaterialVisual, &stColor); SCR_M_SvL0_SaveEntry(_p_stFile, "AmbientColor", SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP( _p_stFile, SCR_EF_SvL0_Scanf, 5, "%f,%f,%f,%f", (float) stColor.xR, (float) stColor.xG, (float) stColor.xB, (float) stColor.xA ); //diffuse color GLI_xGetMaterialDiffuseCoef(hMaterialVisual, &stColor); SCR_M_SvL0_SaveEntry(_p_stFile, "DiffuseColor", SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP( _p_stFile, SCR_EF_SvL0_Scanf, 5, "%f,%f,%f,%f", (float) stColor.xR, (float) stColor.xG, (float) stColor.xB, (float) stColor.xA ); //specular color and coeff //TODO: save alpha component of the color too... when the engine loads its GLI_xGetMaterialSpecularCoef(hMaterialVisual, &lSpecularExponent, &stColor); SCR_M_SvL0_SaveEntry(_p_stFile, "SpecularColor", SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP( _p_stFile, SCR_EF_SvL0_Scanf, 5, "%f,%f,%f,%ld", (float) stColor.xR, (float) stColor.xG, (float) stColor.xB, lSpecularExponent ); //even if a texture is referenced, we save the reference only if the material //has the "textured" attribute... if ( xMType & GLI_C_lIsTextured ) { long lNbTextures = GLI_lGetMaterialNumberOfAnimatedTexture(hMaterialVisual); BOOL bOnlyOne = ((lNbTextures == 1) ? TRUE : FALSE); for ( lNbTextures --; lNbTextures >= 0; lNbTextures -- ) //scan all the textures used by the material { float fDuration; GLI_tdstTexture *p_stTexture; GLI_vGetMaterialAnimatedTexture(hMaterialVisual, lNbTextures, &p_stTexture, &fDuration); //if the visual material references the texture through a section tdoEditorTexture *p_oEditorTexture = (tdoEditorTexture *) gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(p_stTexture); if ( p_oEditorTexture && g_oCoherenceManager.m_fn_ulGetLinkWeight(p_oEditorMaterial, p_oEditorTexture) ) { if ( bOnlyOne ) //if there is only one texture, save it as unanimated { SCR_M_SvL0_SaveEntry(_p_stFile, "AddTexture", SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP( _p_stFile, SCR_EF_SvL0_Scanf, 3, "%d,%s", 0, LPCTSTR(p_oEditorTexture->GetReferencedSectionName()) ); } else //there are more than one: save all textures as components of the animation { SCR_M_SvL0_SaveEntry(_p_stFile, "AddTexture", SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP( _p_stFile, SCR_EF_SvL0_Scanf, 4, "%d,%s,%f", 0, LPCTSTR(p_oEditorTexture->GetReferencedSectionName()), fDuration ); } } } //chrome attribute is relevant only if the material is textured if ( GLI_bIsMaterialChromed(hMaterialVisual) ) { SCR_M_SvL0_SaveEntry(_p_stFile, "Env1", SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, "0"); } //backface attribute too pszType = ( xMType & GLI_C_lIsTestingBackface ) ? "OFF" : "ON"; SCR_M_SvL0_SaveEntry(_p_stFile, "Backface", SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, pszType); } //scroll long lSwitch; float fUSpeed, fVSpeed; GLI_xGetMaterialTextureScrollingCoef(hMaterialVisual, 0, &lSwitch, &fUSpeed, &fVSpeed); if ( lSwitch ) { SCR_M_SvL0_SaveEntry(_p_stFile, "Scroll", SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP( _p_stFile, SCR_EF_SvL0_Scanf, 4, "%ld,%f,%f", 0, fUSpeed, fVSpeed ); } // End Section SCR_M_SvL0_SaveEndSection(_p_stFile, SCR_CC_C_Cfg_EOL); //now the section exists, if this was not the case p_oEditorMaterial->fn_vSectionSaved(); // the section is saved and has no pending notification } //================================================================================= //================================================================================= //================================================================================= // static functions for the class //================================================================================= //================================================================================= //================================================================================= CString tdoEditorVisualMaterial::m_csGetMaterialType() { return C_szVisualMaterialTypeName; } CString tdoEditorVisualMaterial::m_csGetScriptExtension() { return ".vmt"; }