reman3/Rayman_X/cpa/tempgrp/TGM/Src/VMatObj.cpp

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";
}