439 lines
17 KiB
C++
439 lines
17 KiB
C++
//
|
|
/*=============================================================================
|
|
*
|
|
* 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:<name>
|
|
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(<base texture file name (no path)>)
|
|
}
|
|
//=================================================================================*/
|
|
/*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";
|
|
}
|