2048 lines
63 KiB
C++
2048 lines
63 KiB
C++
![]() |
/*
|
||
|
** Command & Conquer Generals Zero Hour(tm)
|
||
|
** Copyright 2025 Electronic Arts Inc.
|
||
|
**
|
||
|
** This program is free software: you can redistribute it and/or modify
|
||
|
** it under the terms of the GNU General Public License as published by
|
||
|
** the Free Software Foundation, either version 3 of the License, or
|
||
|
** (at your option) any later version.
|
||
|
**
|
||
|
** This program is distributed in the hope that it will be useful,
|
||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
** GNU General Public License for more details.
|
||
|
**
|
||
|
** You should have received a copy of the GNU General Public License
|
||
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
/* $Header: /Commando/Code/Tools/max2w3d/w3dutil.cpp 45 8/21/01 10:28a Greg_h $ */
|
||
|
/***********************************************************************************************
|
||
|
*** Confidential - Westwood Studios ***
|
||
|
***********************************************************************************************
|
||
|
* *
|
||
|
* Project Name : Commando Tools - W3D export *
|
||
|
* *
|
||
|
* $Archive:: /Commando/Code/Tools/max2w3d/w3dutil.cpp $*
|
||
|
* *
|
||
|
* $Author:: Greg_h $*
|
||
|
* *
|
||
|
* $Modtime:: 8/21/01 9:41a $*
|
||
|
* *
|
||
|
* $Revision:: 45 $*
|
||
|
* *
|
||
|
*---------------------------------------------------------------------------------------------*
|
||
|
* Functions: *
|
||
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||
|
|
||
|
|
||
|
#include "w3dutil.h"
|
||
|
#include "w3ddesc.h"
|
||
|
#include "rcmenu.h"
|
||
|
#include "util.h"
|
||
|
#include "nodelist.h"
|
||
|
#include "tchar.h"
|
||
|
#include "gamemtl.h"
|
||
|
#include "notify.h"
|
||
|
#include "gennamesdialog.h"
|
||
|
#include "genmtlnamesdialog.h"
|
||
|
#include "genlodextensiondialog.h"
|
||
|
#include "floaterdialog.h"
|
||
|
#include <StdMat.h>
|
||
|
|
||
|
|
||
|
#define DAZZLE_SETTINGS_FILENAME "dazzle.ini"
|
||
|
#define DAZZLE_TYPES_SECTION "Dazzles_List"
|
||
|
#define DAZZLE_SECTION_BUFFERSIZE 32767
|
||
|
|
||
|
|
||
|
static BOOL CALLBACK _settings_form_dlg_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||
|
static BOOL CALLBACK _w3d_utility_tools_dlg_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||
|
|
||
|
static VisibleSelectedINodeFilter _INodeFilter;
|
||
|
|
||
|
|
||
|
/**********************************************************************************************
|
||
|
**
|
||
|
** MaterialReferenceMaker - Class to support Export Utilities in the W3D Tools panel.
|
||
|
**
|
||
|
**********************************************************************************************/
|
||
|
class MaterialReferenceMaker : public ReferenceMaker
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
~MaterialReferenceMaker() {DeleteAllRefs();}
|
||
|
|
||
|
virtual int NumRefs();
|
||
|
virtual RefTargetHandle GetReference (int i);
|
||
|
virtual void SetReference (int i, RefTargetHandle rtarg);
|
||
|
RefResult NotifyRefChanged (Interval changeInt,RefTargetHandle hTarget,PartID& partID, RefMessage message);
|
||
|
|
||
|
Mtl *MaterialPtr;
|
||
|
static int ReferenceCount;
|
||
|
};
|
||
|
|
||
|
int MaterialReferenceMaker::NumRefs()
|
||
|
{
|
||
|
return (ReferenceCount);
|
||
|
}
|
||
|
|
||
|
RefTargetHandle MaterialReferenceMaker::GetReference (int i)
|
||
|
{
|
||
|
assert (i < ReferenceCount);
|
||
|
return (MaterialPtr);
|
||
|
}
|
||
|
|
||
|
void MaterialReferenceMaker::SetReference (int i, RefTargetHandle rtarg)
|
||
|
{
|
||
|
assert (i < ReferenceCount);
|
||
|
MaterialPtr = (Mtl*) rtarg;
|
||
|
}
|
||
|
|
||
|
RefResult MaterialReferenceMaker::NotifyRefChanged(Interval changeInt,RefTargetHandle hTarget,PartID& partID, RefMessage message)
|
||
|
{
|
||
|
return (REF_SUCCEED);
|
||
|
}
|
||
|
|
||
|
int MaterialReferenceMaker::ReferenceCount;
|
||
|
|
||
|
|
||
|
/**********************************************************************************************
|
||
|
**
|
||
|
** SettingsFormClass - code for the W3DUTILITY_SETTINGS_DIALOG. Used in the command panel
|
||
|
** and in the floating settings dialog.
|
||
|
**
|
||
|
**********************************************************************************************/
|
||
|
class SettingsFormClass
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
SettingsFormClass(HWND hwnd);
|
||
|
~SettingsFormClass(void);
|
||
|
|
||
|
bool Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM);
|
||
|
void Selection_Changed(void);
|
||
|
|
||
|
static void Update_All_Instances(void);
|
||
|
|
||
|
private:
|
||
|
|
||
|
void Init(void);
|
||
|
void Destroy(void);
|
||
|
void Disable_Controls(void);
|
||
|
void Update_Controls(INodeListClass * nodelist = NULL);
|
||
|
|
||
|
HWND Hwnd;
|
||
|
ISpinnerControl * RegionSpin;
|
||
|
SettingsFormClass * Next;
|
||
|
|
||
|
static SettingsFormClass * ActiveList;
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
/**********************************************************************************************
|
||
|
**
|
||
|
** W3DUtilityClass - Utility plugin which presents windows controls for setting all of
|
||
|
** the W3D export options for the currently selected nodes
|
||
|
**
|
||
|
**********************************************************************************************/
|
||
|
class W3DUtilityClass : public UtilityObj
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
W3DUtilityClass();
|
||
|
~W3DUtilityClass();
|
||
|
|
||
|
void BeginEditParams(Interface *ip,IUtil *iu);
|
||
|
void EndEditParams(Interface *ip,IUtil *iu);
|
||
|
void SelectionSetChanged(Interface *ip,IUtil *iu);
|
||
|
void DeleteThis() {}
|
||
|
|
||
|
void Select_Hierarchy(void);
|
||
|
void Select_Geometry(void);
|
||
|
void Select_Alpha(void);
|
||
|
void Select_Physical(void);
|
||
|
void Select_Projectile(void);
|
||
|
void Select_Vis(void);
|
||
|
|
||
|
public:
|
||
|
|
||
|
Interface * InterfacePtr;
|
||
|
FloaterDialogClass SettingsFloater;
|
||
|
HWND SettingsPanelHWND;
|
||
|
HWND ToolsPanelHWND;
|
||
|
bool UpdateSpinnerValue;
|
||
|
|
||
|
GenNamesDialogClass::OptionsStruct NameOptions;
|
||
|
GenMtlNamesDialogClass::OptionsStruct MtlNameOptions;
|
||
|
GenLodExtensionDialogClass::OptionsStruct LodExtensionOptions;
|
||
|
|
||
|
int WorkingNameIndex;
|
||
|
|
||
|
enum {
|
||
|
NONE = 0,
|
||
|
HIDE,
|
||
|
SELECT_GEOM,
|
||
|
SELECT_HIER,
|
||
|
SELECT_ALPHA,
|
||
|
SELECT_PHYSICAL,
|
||
|
SELECT_PROJECTILE,
|
||
|
SELECT_VIS,
|
||
|
GENERATE_NAME,
|
||
|
GENERATE_MATERIAL_NAME,
|
||
|
GENERATE_LOD_EXTENSION
|
||
|
};
|
||
|
|
||
|
enum MaterialConversionEnum {
|
||
|
GAME_REFERENCE_COUNT,
|
||
|
GAME_TO_STANDARD,
|
||
|
STANDARD_TO_GAME
|
||
|
};
|
||
|
|
||
|
struct NodeStatesStruct
|
||
|
{
|
||
|
int ExportHierarchy;
|
||
|
int ExportGeometry;
|
||
|
int GeometryTwoSided;
|
||
|
int GeometryHidden;
|
||
|
int GeometryZNormals;
|
||
|
int GeometryVertexAlpha;
|
||
|
int GeometryCastShadow;
|
||
|
int GeometryShatterable;
|
||
|
int GeometryNPatch;
|
||
|
int CollisionPhysical;
|
||
|
int CollisionProjectile;
|
||
|
int CollisionVis;
|
||
|
int CollisionCamera;
|
||
|
int CollisionVehicle;
|
||
|
bool GeometryCameraAligned;
|
||
|
bool GeometryCameraOriented;
|
||
|
bool GeometryNormal;
|
||
|
bool GeometryAABox;
|
||
|
bool GeometryOBBox;
|
||
|
bool GeometryNull;
|
||
|
bool GeometryDazzle;
|
||
|
bool GeometryAggregate;
|
||
|
|
||
|
int DamageRegion;
|
||
|
int DazzleCount;
|
||
|
char DazzleType[128];
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
** Evaluate the status of nodes in the given list
|
||
|
*/
|
||
|
static int eval_tri_state(int totalcount,int oncount);
|
||
|
static void eval_node_states(INodeListClass * node_list,NodeStatesStruct * ns);
|
||
|
|
||
|
/*
|
||
|
** Update the controls in any active settings panels
|
||
|
*/
|
||
|
static void update_settings_controls(INodeListClass * node_list = NULL);
|
||
|
|
||
|
/*
|
||
|
** Modify the state of all selected nodes
|
||
|
*/
|
||
|
static void set_hierarchy_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void set_geometry_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_hidden_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_two_sided_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_znormals_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_vertex_alpha_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_shadow_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_shatterable_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_npatches_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_physical_collision_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_projectile_collision_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_vis_collision_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_camera_collision_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
static void enable_vehicle_collision_in_all_selected(INodeListClass * list,bool onoff);
|
||
|
|
||
|
static void set_geometry_type_in_all_selected(INodeListClass * list,int geotype);
|
||
|
static void set_dazzle_type_in_all_selected(INodeListClass * list,char * dazzletype);
|
||
|
|
||
|
static void set_region_in_all_selected(INodeListClass * list,char region);
|
||
|
|
||
|
/*
|
||
|
** Functions used by the tools rollup in the command panel
|
||
|
*/
|
||
|
void descend_tree(INode * node,int action);
|
||
|
void hide_node(INode * node);
|
||
|
void select_geometry_node(INode * node);
|
||
|
void select_hierarchy_node(INode * node);
|
||
|
void select_alpha_node(INode * node);
|
||
|
void select_physical_node(INode * node);
|
||
|
void select_projectile_node(INode * node);
|
||
|
void select_vis_node(INode * node);
|
||
|
bool is_alpha_material(Mtl * nodemtl);
|
||
|
bool is_alpha_mesh(INode * node,Mtl * nodemtl);
|
||
|
|
||
|
void generate_names(void);
|
||
|
void generate_node_name(INode * node);
|
||
|
void generate_material_names(void);
|
||
|
void generate_material_names_for_node(INode * node);
|
||
|
void generate_material_names(Mtl * mtl);
|
||
|
void generate_lod_extensions(void);
|
||
|
void generate_lod_ext(INode * node);
|
||
|
|
||
|
void create_floater(void);
|
||
|
|
||
|
void export_with_standard_materials();
|
||
|
int convert_materials (MaterialConversionEnum conversion, MaterialReferenceMaker *gamenodematerials);
|
||
|
StdMat * new_standard_material (GameMtl *gamemtl);
|
||
|
|
||
|
static W3DAppData0Struct * get_app_data_0(INode * node);
|
||
|
static W3DAppData1Struct * get_app_data_1(INode * node);
|
||
|
static W3DAppData2Struct * get_app_data_2(INode * node);
|
||
|
static W3DDazzleAppDataStruct * get_dazzle_app_data(INode * node);
|
||
|
};
|
||
|
|
||
|
static W3DUtilityClass TheW3DUtility;
|
||
|
|
||
|
|
||
|
/**********************************************************************************************
|
||
|
**
|
||
|
** W3DUtilityClassDesc - Class Descriptor for the W3D Utility
|
||
|
**
|
||
|
**********************************************************************************************/
|
||
|
class W3DUtilityClassDesc:public ClassDesc
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
int IsPublic() { return 1; }
|
||
|
void * Create(BOOL loading = FALSE) { return &TheW3DUtility; }
|
||
|
const TCHAR * ClassName() { return Get_String(IDS_W3D_UTILITY_CLASS_NAME); }
|
||
|
SClass_ID SuperClassID() { return UTILITY_CLASS_ID; }
|
||
|
Class_ID ClassID() { return W3DUtilityClassID; }
|
||
|
const TCHAR* Category() { return Get_String(IDS_W3DMENU_CATEGORY); }
|
||
|
};
|
||
|
|
||
|
static W3DUtilityClassDesc W3DUtilityDesc;
|
||
|
|
||
|
ClassDesc * Get_W3D_Utility_Desc(void)
|
||
|
{
|
||
|
return &W3DUtilityDesc;
|
||
|
}
|
||
|
|
||
|
/**********************************************************************************************
|
||
|
**
|
||
|
** W3DUtilityClass Implementation
|
||
|
**
|
||
|
**********************************************************************************************/
|
||
|
W3DUtilityClass::W3DUtilityClass(void)
|
||
|
{
|
||
|
InterfacePtr = NULL;
|
||
|
SettingsPanelHWND = NULL;
|
||
|
ToolsPanelHWND = NULL;
|
||
|
UpdateSpinnerValue = true;
|
||
|
}
|
||
|
|
||
|
W3DUtilityClass::~W3DUtilityClass(void)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::BeginEditParams(Interface *ip,IUtil *iu)
|
||
|
{
|
||
|
InterfacePtr = ip;
|
||
|
|
||
|
SettingsPanelHWND = InterfacePtr->AddRollupPage(
|
||
|
AppInstance,
|
||
|
MAKEINTRESOURCE(IDD_W3DUTILITY_SETTINGS_DIALOG),
|
||
|
_settings_form_dlg_proc,
|
||
|
Get_String(IDS_W3DUTILITY_SETTINGS),
|
||
|
0);
|
||
|
|
||
|
ToolsPanelHWND = InterfacePtr->AddRollupPage(
|
||
|
AppInstance,
|
||
|
MAKEINTRESOURCE(IDD_W3DUTILITY_TOOLS_DIALOG),
|
||
|
_w3d_utility_tools_dlg_proc,
|
||
|
Get_String(IDS_W3DUTILITY_TOOLS),
|
||
|
0);
|
||
|
|
||
|
|
||
|
// TheRCMenu.Bind(TheW3DUtility.InterfacePtr,&TheW3DUtility);
|
||
|
// RightClickMenuManager *rcm = ip->GetRightClickMenuManager();
|
||
|
// if (TheRCMenu.Installed!=TRUE) {
|
||
|
// rcm->Register(&TheRCMenu);
|
||
|
// }
|
||
|
|
||
|
SettingsFormClass::Update_All_Instances();
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::EndEditParams(Interface *ip,IUtil *iu)
|
||
|
{
|
||
|
InterfacePtr = NULL;
|
||
|
|
||
|
ip->DeleteRollupPage(SettingsPanelHWND);
|
||
|
ip->DeleteRollupPage(ToolsPanelHWND);
|
||
|
|
||
|
SettingsPanelHWND = NULL;
|
||
|
ToolsPanelHWND = NULL;
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::SelectionSetChanged(Interface *ip,IUtil *iu)
|
||
|
{
|
||
|
// (gth) the settings panels which need to respond to the selection set changing
|
||
|
// are now registered directly with MAX and don't need to be updated here
|
||
|
// update_dialog();
|
||
|
}
|
||
|
|
||
|
int W3DUtilityClass::eval_tri_state(int totalcount,int oncount)
|
||
|
{
|
||
|
if (oncount == 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
if (oncount == totalcount) {
|
||
|
return 1;
|
||
|
}
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::eval_node_states(INodeListClass * list,NodeStatesStruct * ns)
|
||
|
{
|
||
|
// initialize the counters and booleans
|
||
|
ns->ExportHierarchy = 0;
|
||
|
ns->ExportGeometry = 0;
|
||
|
ns->GeometryHidden = 0;
|
||
|
ns->GeometryTwoSided = 0;
|
||
|
ns->GeometryZNormals = 0;
|
||
|
ns->GeometryVertexAlpha = 0;
|
||
|
ns->GeometryCastShadow = 0;
|
||
|
ns->GeometryShatterable = 0;
|
||
|
ns->GeometryNPatch = 0;
|
||
|
ns->CollisionPhysical = 0;
|
||
|
ns->CollisionProjectile = 0;
|
||
|
ns->CollisionVis = 0;
|
||
|
ns->CollisionCamera = 0;
|
||
|
ns->CollisionVehicle = 0;
|
||
|
|
||
|
ns->GeometryCameraAligned = false;
|
||
|
ns->GeometryCameraOriented = false;
|
||
|
ns->GeometryNormal = false;
|
||
|
ns->GeometryAABox = false;
|
||
|
ns->GeometryOBBox = false;
|
||
|
ns->GeometryNull = false;
|
||
|
ns->GeometryDazzle = false;
|
||
|
ns->GeometryAggregate = false;
|
||
|
|
||
|
/*
|
||
|
** ns->DamageRegion will be MAX_DAMAGE_REGIONS if not all
|
||
|
** of the selected nodes are in the same damage region. If
|
||
|
** they are, then ns->DamageRegion will be the region they
|
||
|
** share.
|
||
|
*/
|
||
|
if (list->Num_Nodes() > 0)
|
||
|
{
|
||
|
// Use the first damage region for comparing to the others.
|
||
|
W3DAppData1Struct *wdata = get_app_data_1((*list)[0]);
|
||
|
ns->DamageRegion = wdata->DamageRegion;
|
||
|
}
|
||
|
else
|
||
|
ns->DamageRegion = MAX_DAMAGE_REGIONS;
|
||
|
|
||
|
/*
|
||
|
** ns->DazzleType will be DEFAULT if not all of the selected
|
||
|
** nodes are the same. If they are the same, it will be the
|
||
|
** dazzle type that they all share
|
||
|
*/
|
||
|
ns->DazzleCount = 0;
|
||
|
if (list->Num_Nodes() > 0) {
|
||
|
W3DDazzleAppDataStruct * dazzledata = get_dazzle_app_data((*list)[0]);
|
||
|
strncpy(ns->DazzleType,dazzledata->DazzleType,sizeof(ns->DazzleType));
|
||
|
} else {
|
||
|
strcpy(ns->DazzleType,"DEFAULT");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** evaluate each node
|
||
|
*/
|
||
|
for (unsigned int ni=0; ni<list->Num_Nodes(); ni++) {
|
||
|
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*list)[ni]);
|
||
|
assert(wdata);
|
||
|
|
||
|
ns->ExportHierarchy += (wdata->Is_Bone() ? 1 : 0);
|
||
|
ns->ExportGeometry += (wdata->Is_Geometry() ? 1 : 0);
|
||
|
ns->GeometryHidden += (wdata->Is_Hidden_Enabled() ? 1 : 0);
|
||
|
ns->GeometryTwoSided += (wdata->Is_Two_Sided_Enabled() ? 1 : 0);
|
||
|
ns->GeometryZNormals += (wdata->Is_ZNormals_Enabled() ? 1 : 0);
|
||
|
ns->GeometryVertexAlpha += (wdata->Is_Vertex_Alpha_Enabled() ? 1 : 0);
|
||
|
ns->GeometryCastShadow += (wdata->Is_Shadow_Enabled() ? 1 : 0);
|
||
|
ns->GeometryShatterable += (wdata->Is_Shatterable_Enabled() ? 1 : 0);
|
||
|
ns->GeometryNPatch += (wdata->Is_NPatchable_Enabled() ? 1 : 0);
|
||
|
ns->CollisionPhysical += (wdata->Is_Physical_Collision_Enabled() ? 1 : 0);
|
||
|
ns->CollisionProjectile += (wdata->Is_Projectile_Collision_Enabled() ? 1 : 0);
|
||
|
ns->CollisionVis += (wdata->Is_Vis_Collision_Enabled() ? 1 : 0);
|
||
|
ns->CollisionCamera += (wdata->Is_Camera_Collision_Enabled() ? 1 : 0);
|
||
|
ns->CollisionVehicle += (wdata->Is_Vehicle_Collision_Enabled() ? 1 : 0);
|
||
|
|
||
|
switch (wdata->Get_Geometry_Type()) {
|
||
|
case W3DAppData2Struct::GEO_TYPE_CAMERA_ALIGNED: ns->GeometryCameraAligned = true; break;
|
||
|
case W3DAppData2Struct::GEO_TYPE_CAMERA_ORIENTED: ns->GeometryCameraOriented = true; break;
|
||
|
case W3DAppData2Struct::GEO_TYPE_NORMAL_MESH: ns->GeometryNormal = true; break;
|
||
|
case W3DAppData2Struct::GEO_TYPE_AABOX: ns->GeometryAABox = true; break;
|
||
|
case W3DAppData2Struct::GEO_TYPE_OBBOX: ns->GeometryOBBox = true; break;
|
||
|
case W3DAppData2Struct::GEO_TYPE_NULL: ns->GeometryNull = true; break;
|
||
|
case W3DAppData2Struct::GEO_TYPE_DAZZLE: ns->GeometryDazzle = true; ns->DazzleCount++; break;
|
||
|
case W3DAppData2Struct::GEO_TYPE_AGGREGATE: ns->GeometryAggregate = true; break;
|
||
|
}
|
||
|
|
||
|
// Compare this damage region to our existing one. If it's not the same,
|
||
|
// use MAX_DAMAGE_REGION (an invalid value) as a sentinel value.
|
||
|
if (ns->DamageRegion != MAX_DAMAGE_REGIONS)
|
||
|
{
|
||
|
W3DAppData1Struct *wdata1 = get_app_data_1((*list)[ni]);
|
||
|
assert(wdata1);
|
||
|
if (wdata1->DamageRegion != ns->DamageRegion)
|
||
|
ns->DamageRegion = MAX_DAMAGE_REGIONS;
|
||
|
}
|
||
|
|
||
|
// compare this objects dazzle type to our existing one. If its not
|
||
|
// the same, use 'DEFAULT'.
|
||
|
W3DDazzleAppDataStruct * dazzledata = get_dazzle_app_data((*list)[ni]);
|
||
|
if (strcmp(ns->DazzleType,dazzledata->DazzleType) != 0) {
|
||
|
strcpy(ns->DazzleType,"DEFAULT");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If any of the counters are zero, that means none of the objects had that
|
||
|
// bit set. If any of them are equal to the number of objects, then they
|
||
|
// all had that bit set. Otherwise, there was a mix and we should use the
|
||
|
// third state for the checkbox (greyed out check).
|
||
|
int count = list->Num_Nodes();
|
||
|
ns->ExportHierarchy = eval_tri_state(count, ns->ExportHierarchy);
|
||
|
ns->ExportGeometry = eval_tri_state(count, ns->ExportGeometry);
|
||
|
ns->GeometryHidden = eval_tri_state(count, ns->GeometryHidden);
|
||
|
ns->GeometryTwoSided = eval_tri_state(count, ns->GeometryTwoSided);
|
||
|
ns->GeometryZNormals = eval_tri_state(count, ns->GeometryZNormals);
|
||
|
ns->GeometryVertexAlpha = eval_tri_state(count, ns->GeometryVertexAlpha);
|
||
|
ns->GeometryCastShadow = eval_tri_state(count, ns->GeometryCastShadow);
|
||
|
ns->GeometryShatterable = eval_tri_state(count, ns->GeometryShatterable);
|
||
|
ns->GeometryNPatch = eval_tri_state(count, ns->GeometryNPatch);
|
||
|
ns->CollisionPhysical = eval_tri_state(count, ns->CollisionPhysical);
|
||
|
ns->CollisionProjectile = eval_tri_state(count, ns->CollisionProjectile);
|
||
|
ns->CollisionVis = eval_tri_state(count, ns->CollisionVis);
|
||
|
ns->CollisionCamera = eval_tri_state(count, ns->CollisionCamera);
|
||
|
ns->CollisionVehicle = eval_tri_state(count, ns->CollisionVehicle);
|
||
|
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::update_settings_controls(INodeListClass * node_list)
|
||
|
{
|
||
|
SettingsFormClass::Update_All_Instances();
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::set_hierarchy_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Export_Transform(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::set_geometry_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Export_Geometry(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_hidden_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Hidden(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_two_sided_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Two_Sided(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_znormals_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_ZNormals(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_vertex_alpha_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Vertex_Alpha(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_shadow_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Shadow(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_shatterable_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Shatterable(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_npatches_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_NPatchable(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_physical_collision_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Physical_Collision(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_projectile_collision_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Projectile_Collision(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_vis_collision_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Vis_Collision(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_camera_collision_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Camera_Collision(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::enable_vehicle_collision_in_all_selected(INodeListClass * node_list,bool onoff)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Enable_Vehicle_Collision(onoff);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::set_geometry_type_in_all_selected(INodeListClass * node_list,int geotype)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DAppData2Struct * wdata = get_app_data_2((*node_list)[ni]);
|
||
|
wdata->Set_Geometry_Type((W3DAppData2Struct::GeometryTypeEnum)geotype);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::set_dazzle_type_in_all_selected(INodeListClass * node_list,char * dazzle_type)
|
||
|
{
|
||
|
for (unsigned int ni=0; ni<node_list->Num_Nodes(); ni++) {
|
||
|
W3DDazzleAppDataStruct * dazzledata = get_dazzle_app_data((*node_list)[ni]);
|
||
|
strncpy(dazzledata->DazzleType,dazzle_type,sizeof(dazzledata->DazzleType) - 1);
|
||
|
}
|
||
|
update_settings_controls(node_list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::set_region_in_all_selected(INodeListClass * list,char region)
|
||
|
{
|
||
|
if (list->Num_Nodes() == 0) return;
|
||
|
|
||
|
// Damage regions are stored in each node's AppData1.
|
||
|
for (int i = 0; i < list->Num_Nodes(); i++)
|
||
|
{
|
||
|
W3DAppData1Struct *wdata = get_app_data_1((*list)[i]);
|
||
|
wdata->DamageRegion = region;
|
||
|
}
|
||
|
update_settings_controls(list);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::generate_names(void)
|
||
|
{
|
||
|
GenNamesDialogClass dialog(InterfacePtr);
|
||
|
bool retval = dialog.Get_Options(&NameOptions);
|
||
|
WorkingNameIndex = NameOptions.NameIndex;
|
||
|
|
||
|
if (retval) {
|
||
|
descend_tree(InterfacePtr->GetRootNode(),GENERATE_NAME);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::generate_material_names(void)
|
||
|
{
|
||
|
GenMtlNamesDialogClass dialog(InterfacePtr);
|
||
|
bool retval = dialog.Get_Options(&MtlNameOptions);
|
||
|
WorkingNameIndex = MtlNameOptions.NameIndex;
|
||
|
|
||
|
if (retval) {
|
||
|
descend_tree(InterfacePtr->GetRootNode(),GENERATE_MATERIAL_NAME);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::generate_lod_extensions(void)
|
||
|
{
|
||
|
GenLodExtensionDialogClass dialog(InterfacePtr);
|
||
|
bool retval = dialog.Get_Options(&LodExtensionOptions);
|
||
|
|
||
|
if (retval) {
|
||
|
descend_tree(InterfacePtr->GetRootNode(),GENERATE_LOD_EXTENSION);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::generate_lod_ext(INode * node)
|
||
|
{
|
||
|
/*
|
||
|
** Only works on selected nodes.
|
||
|
*/
|
||
|
if (!node->Selected())
|
||
|
return;
|
||
|
|
||
|
/*
|
||
|
** If this node already has an LOD extension, we'll replace it
|
||
|
** with the new LOD index. Otherwise we'll tack it on the end.
|
||
|
** Display a error message if the name is too long to append
|
||
|
** the extension, and skip the node without changing the name.
|
||
|
*/
|
||
|
char msg[256];
|
||
|
char newname[W3D_NAME_LEN];
|
||
|
char *oldname = node->GetName();
|
||
|
char *ext = strrchr(oldname, '.');
|
||
|
int old_lod;
|
||
|
if ( (ext != NULL) && (sscanf(ext, ".%d", &old_lod) == 1) )
|
||
|
{
|
||
|
/*
|
||
|
** An existing LOD index. If it's different than the new
|
||
|
** one, replace it.
|
||
|
*/
|
||
|
if (old_lod == LodExtensionOptions.LodIndex)
|
||
|
return; // same lod index
|
||
|
|
||
|
/*
|
||
|
** Room for the new extension? (2 because when we export, the extension will,
|
||
|
** be replaced by a single character [A..Z] to indicate the LOD level.
|
||
|
** ie. 2==strlen("A")+1)
|
||
|
*/
|
||
|
if (ext - oldname + 2 <= W3D_NAME_LEN)
|
||
|
{
|
||
|
*ext = '\0';
|
||
|
sprintf(newname, "%s.%02d", oldname, LodExtensionOptions.LodIndex);
|
||
|
*ext = '.';
|
||
|
node->SetName(newname);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ext = '\0';
|
||
|
sprintf(msg, "The maximum W3D object name is %d characters. Adding the LOD "
|
||
|
"extension to \"%s\" will pass this limit! Please shorten its name.",
|
||
|
W3D_NAME_LEN - 1, oldname);
|
||
|
*ext = '.';
|
||
|
MessageBox(NULL, msg, "Error", MB_OK);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/*
|
||
|
** Room for the new extension? (2 because when we export, the extension will,
|
||
|
** be replaced by a single character [A..Z] to indicate the LOD level.
|
||
|
** ie. 2==strlen("A")+1)
|
||
|
*/
|
||
|
if (strlen(oldname) + 2 <= W3D_NAME_LEN)
|
||
|
{
|
||
|
sprintf(newname, "%s.%02d", oldname, LodExtensionOptions.LodIndex);
|
||
|
node->SetName(newname);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sprintf(msg, "The maximum W3D object name is %d characters. Adding the LOD "
|
||
|
"extension to \"%s\" will pass this limit! Please shorten its name.",
|
||
|
W3D_NAME_LEN - 1, oldname);
|
||
|
MessageBox(NULL, msg, "Error", MB_OK);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::create_floater(void)
|
||
|
{
|
||
|
SettingsFloater.Create(InterfacePtr,IDD_W3DUTILITY_SETTINGS_DIALOG,_settings_form_dlg_proc);
|
||
|
SettingsFormClass::Update_All_Instances();
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::export_with_standard_materials()
|
||
|
{
|
||
|
char *convertingmessage = "Converting materials...";
|
||
|
|
||
|
// Count the no. of references to game materials.
|
||
|
MaterialReferenceMaker::ReferenceCount = convert_materials (GAME_REFERENCE_COUNT, NULL);
|
||
|
|
||
|
MaterialReferenceMaker *gamenodematerials = NULL;
|
||
|
|
||
|
if (MaterialReferenceMaker::ReferenceCount > 0) {
|
||
|
gamenodematerials = new MaterialReferenceMaker [MaterialReferenceMaker::ReferenceCount];
|
||
|
assert (gamenodematerials != NULL);
|
||
|
}
|
||
|
|
||
|
InterfacePtr->PushPrompt (convertingmessage);
|
||
|
SetCursor (LoadCursor (NULL, IDC_WAIT));
|
||
|
convert_materials (GAME_TO_STANDARD, gamenodematerials);
|
||
|
InterfacePtr->PopPrompt();
|
||
|
InterfacePtr->FileExport();
|
||
|
UpdateWindow (InterfacePtr->GetMAXHWnd());
|
||
|
InterfacePtr->PushPrompt (convertingmessage);
|
||
|
SetCursor (LoadCursor (NULL, IDC_WAIT));
|
||
|
convert_materials (STANDARD_TO_GAME, gamenodematerials);
|
||
|
InterfacePtr->PopPrompt();
|
||
|
|
||
|
// Clean-up.
|
||
|
if (gamenodematerials != NULL) delete [] gamenodematerials;
|
||
|
}
|
||
|
|
||
|
int W3DUtilityClass::convert_materials (MaterialConversionEnum conversion, MaterialReferenceMaker *gamenodematerials)
|
||
|
{
|
||
|
int gamenodematerialindex = 0;
|
||
|
|
||
|
INode *rootnode = InterfacePtr->GetRootNode();
|
||
|
if (rootnode != NULL) {
|
||
|
|
||
|
INodeListClass *meshlist = new INodeListClass (rootnode, 0);
|
||
|
if (meshlist != NULL) {
|
||
|
|
||
|
for (unsigned nodeindex = 0; nodeindex < meshlist->Num_Nodes(); nodeindex++) {
|
||
|
|
||
|
Mtl *nodemtl = ((*meshlist) [nodeindex])->GetMtl();
|
||
|
|
||
|
// Is this a non-null material?
|
||
|
if (nodemtl != NULL) {
|
||
|
|
||
|
// Is this not a multi-material?
|
||
|
if (!nodemtl->IsMultiMtl()) {
|
||
|
|
||
|
switch (conversion) {
|
||
|
|
||
|
case GAME_REFERENCE_COUNT:
|
||
|
if (nodemtl->ClassID() == GameMaterialClassID) {
|
||
|
assert (((GameMtl*) nodemtl)->Substitute_Material() == NULL);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case GAME_TO_STANDARD:
|
||
|
|
||
|
if (nodemtl->ClassID() == GameMaterialClassID) {
|
||
|
|
||
|
// Make a reference to the game material to ensure that it is not deleted by the system.
|
||
|
gamenodematerials [gamenodematerialindex].MakeRefByID (FOREVER, gamenodematerialindex, nodemtl);
|
||
|
|
||
|
// Does this material already have an equivalent standard material?
|
||
|
if (((GameMtl*) nodemtl)->Substitute_Material() == NULL) {
|
||
|
((GameMtl*) nodemtl)->Set_Substitute_Material (new_standard_material ((GameMtl*) nodemtl));
|
||
|
}
|
||
|
((*meshlist) [nodeindex])->SetMtl (((GameMtl*) nodemtl)->Substitute_Material());
|
||
|
|
||
|
} else {
|
||
|
gamenodematerials [gamenodematerialindex].MaterialPtr = NULL;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case STANDARD_TO_GAME:
|
||
|
|
||
|
// Change materials to game materials if they were previously game materials before being
|
||
|
// converted to standard materials.
|
||
|
if (gamenodematerials [gamenodematerialindex].MaterialPtr != NULL) {
|
||
|
((*meshlist) [nodeindex])->SetMtl (gamenodematerials [gamenodematerialindex].MaterialPtr);
|
||
|
((GameMtl*) gamenodematerials [gamenodematerialindex].MaterialPtr)->Set_Substitute_Material (NULL);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
gamenodematerialindex++;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
// For each sub-material...
|
||
|
for (int materialindex = 0; materialindex < nodemtl->NumSubMtls(); materialindex++) {
|
||
|
|
||
|
Mtl *submaterial = nodemtl->GetSubMtl (materialindex);
|
||
|
|
||
|
// Is this a non-null submaterial?
|
||
|
if (submaterial != NULL) {
|
||
|
|
||
|
switch (conversion) {
|
||
|
|
||
|
case GAME_REFERENCE_COUNT:
|
||
|
if (submaterial->ClassID() == GameMaterialClassID) {
|
||
|
assert (((GameMtl*) submaterial)->Substitute_Material() == NULL);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case GAME_TO_STANDARD:
|
||
|
|
||
|
if (submaterial->ClassID() == GameMaterialClassID) {
|
||
|
|
||
|
// Make a reference to the game material to ensure that it is not deleted by the system.
|
||
|
gamenodematerials [gamenodematerialindex].MakeRefByID (FOREVER, gamenodematerialindex, submaterial);
|
||
|
|
||
|
// Does this material already have an equivalent standard material?
|
||
|
if (((GameMtl*) submaterial)->Substitute_Material() == NULL) {
|
||
|
((GameMtl*) submaterial)->Set_Substitute_Material (new_standard_material ((GameMtl*) submaterial));
|
||
|
}
|
||
|
nodemtl->SetSubMtl (materialindex, ((GameMtl*) submaterial)->Substitute_Material());
|
||
|
|
||
|
} else {
|
||
|
gamenodematerials [gamenodematerialindex].MaterialPtr = NULL;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case STANDARD_TO_GAME:
|
||
|
|
||
|
// Change materials to game materials if they were previously game materials before being
|
||
|
// converted to standard materials.
|
||
|
if (gamenodematerials [gamenodematerialindex].MaterialPtr != NULL) {
|
||
|
nodemtl->SetSubMtl (materialindex, gamenodematerials [gamenodematerialindex].MaterialPtr);
|
||
|
((GameMtl*) gamenodematerials [gamenodematerialindex].MaterialPtr)->Set_Substitute_Material (NULL);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
gamenodematerialindex++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Clean-up.
|
||
|
delete meshlist;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (gamenodematerialindex);
|
||
|
}
|
||
|
|
||
|
StdMat *W3DUtilityClass::new_standard_material (GameMtl *gamemtl)
|
||
|
{
|
||
|
Color emissive;
|
||
|
|
||
|
// Create a new standard material.
|
||
|
StdMat *stdmtl = NewDefaultStdMat();
|
||
|
|
||
|
// Set its properties by translating the supplied game material.
|
||
|
// NOTE 0: Only consider pass 0 in the game material - ignore all other passes.
|
||
|
// NOTE 1: Use defaults for all standard material attributes that cannot be
|
||
|
// converted from the game material in a meaningful way.
|
||
|
stdmtl->SetName (gamemtl->GetName());
|
||
|
stdmtl->SetAmbient (gamemtl->GetAmbient(), 0);
|
||
|
stdmtl->SetDiffuse (gamemtl->GetDiffuse(), 0);
|
||
|
stdmtl->SetSpecular (gamemtl->GetSpecular(), 0);
|
||
|
stdmtl->SetOpacity (gamemtl->Get_Opacity (0, 0), 0);
|
||
|
stdmtl->SetShininess (gamemtl->Get_Shininess (0, 0), 0);
|
||
|
stdmtl->SetShinStr (gamemtl->GetShinStr(), 0);
|
||
|
stdmtl->SetSubTexmap (ID_DI, gamemtl->Get_Texture (0, 0));
|
||
|
emissive = gamemtl->Get_Emissive (0, 0);
|
||
|
stdmtl->SetSelfIllum ((emissive.r + emissive.g + emissive.b) / 3.0f, 0);
|
||
|
|
||
|
return (stdmtl);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::Select_Hierarchy(void)
|
||
|
{
|
||
|
InterfacePtr->SelectNode(NULL);
|
||
|
INode * root = InterfacePtr->GetRootNode();
|
||
|
descend_tree(root,SELECT_HIER);
|
||
|
InterfacePtr->ForceCompleteRedraw();
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::Select_Geometry(void)
|
||
|
{
|
||
|
InterfacePtr->SelectNode(NULL);
|
||
|
INode * root = InterfacePtr->GetRootNode();
|
||
|
descend_tree(root,SELECT_GEOM);
|
||
|
InterfacePtr->ForceCompleteRedraw();
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::Select_Alpha(void)
|
||
|
{
|
||
|
InterfacePtr->SelectNode(NULL);
|
||
|
INode * root = InterfacePtr->GetRootNode();
|
||
|
descend_tree(root,SELECT_ALPHA);
|
||
|
InterfacePtr->ForceCompleteRedraw();
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::Select_Physical(void)
|
||
|
{
|
||
|
InterfacePtr->SelectNode(NULL);
|
||
|
INode * root = InterfacePtr->GetRootNode();
|
||
|
descend_tree(root,SELECT_PHYSICAL);
|
||
|
InterfacePtr->ForceCompleteRedraw();
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::Select_Projectile(void)
|
||
|
{
|
||
|
InterfacePtr->SelectNode(NULL);
|
||
|
INode * root = InterfacePtr->GetRootNode();
|
||
|
descend_tree(root,SELECT_PROJECTILE);
|
||
|
InterfacePtr->ForceCompleteRedraw();
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::Select_Vis(void)
|
||
|
{
|
||
|
InterfacePtr->SelectNode(NULL);
|
||
|
INode * root = InterfacePtr->GetRootNode();
|
||
|
descend_tree(root,SELECT_VIS);
|
||
|
InterfacePtr->ForceCompleteRedraw();
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::descend_tree(INode * node,int func)
|
||
|
{
|
||
|
if (!node) return;
|
||
|
|
||
|
switch (func)
|
||
|
{
|
||
|
case HIDE:
|
||
|
hide_node(node);
|
||
|
break;
|
||
|
|
||
|
case SELECT_GEOM:
|
||
|
select_geometry_node(node);
|
||
|
break;
|
||
|
|
||
|
case SELECT_HIER:
|
||
|
select_hierarchy_node(node);
|
||
|
break;
|
||
|
|
||
|
case SELECT_ALPHA:
|
||
|
select_alpha_node(node);
|
||
|
break;
|
||
|
|
||
|
case SELECT_PHYSICAL:
|
||
|
select_physical_node(node);
|
||
|
break;
|
||
|
|
||
|
case SELECT_PROJECTILE:
|
||
|
select_projectile_node(node);
|
||
|
break;
|
||
|
|
||
|
case SELECT_VIS:
|
||
|
select_vis_node(node);
|
||
|
break;
|
||
|
|
||
|
case GENERATE_NAME:
|
||
|
generate_node_name(node);
|
||
|
break;
|
||
|
|
||
|
case GENERATE_MATERIAL_NAME:
|
||
|
generate_material_names_for_node(node);
|
||
|
break;
|
||
|
|
||
|
case GENERATE_LOD_EXTENSION:
|
||
|
generate_lod_ext(node);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
};
|
||
|
|
||
|
for (int i=0; i<node->NumberOfChildren(); i++) {
|
||
|
INode * child = node->GetChildNode(i);
|
||
|
descend_tree(child,func);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::hide_node(INode * node)
|
||
|
{
|
||
|
if (!node->IsHidden()) node->Hide(TRUE);
|
||
|
InterfacePtr->NodeInvalidateRect(node);
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::select_geometry_node(INode * node)
|
||
|
{
|
||
|
if (Is_Geometry(node) && !node->IsHidden()) {
|
||
|
InterfacePtr->SelectNode(node,0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::select_hierarchy_node(INode * node)
|
||
|
{
|
||
|
if (Is_Bone(node) && !node->IsHidden()) {
|
||
|
InterfacePtr->SelectNode(node,0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::select_alpha_node(INode * node)
|
||
|
{
|
||
|
if (node->IsHidden() || !Is_Geometry(node)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Mtl * nodemtl = node->GetMtl();
|
||
|
if (is_alpha_material(nodemtl)) {
|
||
|
if (is_alpha_mesh(node,nodemtl)) {
|
||
|
InterfacePtr->SelectNode(node,0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::select_physical_node(INode * node)
|
||
|
{
|
||
|
if (!node->IsHidden() && Is_Geometry(node) && Is_Physical_Collision(node)) {
|
||
|
InterfacePtr->SelectNode(node,0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::select_projectile_node(INode * node)
|
||
|
{
|
||
|
if (!node->IsHidden() && Is_Geometry(node) && Is_Projectile_Collision(node)) {
|
||
|
InterfacePtr->SelectNode(node,0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::select_vis_node(INode * node)
|
||
|
{
|
||
|
if (!node->IsHidden() && Is_Geometry(node) && Is_Vis_Collision(node)) {
|
||
|
InterfacePtr->SelectNode(node,0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool W3DUtilityClass::is_alpha_material(Mtl * nodemtl)
|
||
|
{
|
||
|
if (nodemtl == NULL) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool is_alpha = false;
|
||
|
if (nodemtl->IsMultiMtl()) {
|
||
|
for (int mi=0; mi<nodemtl->NumSubMtls(); mi++) {
|
||
|
is_alpha |= is_alpha_material(nodemtl->GetSubMtl(mi));
|
||
|
}
|
||
|
} else {
|
||
|
if (nodemtl->ClassID() == GameMaterialClassID) {
|
||
|
GameMtl * gamemtl = (GameMtl *)nodemtl;
|
||
|
|
||
|
if ( (gamemtl->Get_Dest_Blend(0) == W3DSHADER_DESTBLENDFUNC_SRC_ALPHA) ||
|
||
|
(gamemtl->Get_Dest_Blend(0) == W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_ALPHA) ||
|
||
|
(gamemtl->Get_Src_Blend(0) == W3DSHADER_SRCBLENDFUNC_SRC_ALPHA) ||
|
||
|
(gamemtl->Get_Src_Blend(0) == W3DSHADER_SRCBLENDFUNC_ONE_MINUS_SRC_ALPHA) ||
|
||
|
(gamemtl->Get_Alpha_Test(0) == W3DSHADER_ALPHATEST_ENABLE) )
|
||
|
{
|
||
|
is_alpha = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return is_alpha;
|
||
|
}
|
||
|
|
||
|
bool W3DUtilityClass::is_alpha_mesh(INode * node,Mtl * nodemtl)
|
||
|
{
|
||
|
Object * obj = node->EvalWorldState(0).obj;
|
||
|
TriObject * tri = (TriObject *)obj->ConvertToType(0, triObjectClassID);
|
||
|
|
||
|
if (tri != NULL) {
|
||
|
Mesh & mesh = tri->mesh;
|
||
|
|
||
|
int face_index;
|
||
|
int mat_index;
|
||
|
|
||
|
if (nodemtl == NULL) {
|
||
|
|
||
|
return false;
|
||
|
|
||
|
} else if (nodemtl->NumSubMtls() <= 1) {
|
||
|
|
||
|
return is_alpha_material(nodemtl);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
int sub_mtl_count = nodemtl->NumSubMtls();
|
||
|
bool * sub_mtl_flags = new bool[sub_mtl_count];
|
||
|
|
||
|
// Initialize each sub-material flag to false (indicates that the material is un-used)
|
||
|
for (mat_index=0; mat_index<sub_mtl_count; mat_index++) {
|
||
|
sub_mtl_flags[mat_index] = false;
|
||
|
}
|
||
|
|
||
|
// Set a true for each material actually referenced by the mesh
|
||
|
for (face_index=0; face_index<mesh.getNumFaces(); face_index++) {
|
||
|
int max_mat_index = mesh.faces[face_index].getMatID();
|
||
|
int mat_index = (max_mat_index % sub_mtl_count);
|
||
|
sub_mtl_flags[mat_index] = true;
|
||
|
}
|
||
|
|
||
|
// Loop over the used materials and return true if any are alpha materials
|
||
|
for (mat_index=0; mat_index<sub_mtl_count; mat_index++) {
|
||
|
if (sub_mtl_flags[mat_index]) {
|
||
|
if (is_alpha_material(nodemtl->GetSubMtl(mat_index))) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::generate_node_name(INode * node)
|
||
|
{
|
||
|
TCHAR temp_string[256];
|
||
|
|
||
|
if (NameOptions.OnlyAffectSelected && !node->Selected()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!Is_Bone(node) && !Is_Geometry(node)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (NameOptions.AssignNames) {
|
||
|
_stprintf(temp_string,"%s%03d",NameOptions.RootName,WorkingNameIndex);
|
||
|
node->SetName(temp_string);
|
||
|
WorkingNameIndex++;
|
||
|
}
|
||
|
|
||
|
if (NameOptions.AssignPrefix) {
|
||
|
_stprintf(temp_string,"%s%s",NameOptions.PrefixName,node->GetName());
|
||
|
node->SetName(temp_string);
|
||
|
}
|
||
|
|
||
|
if (NameOptions.AssignSuffix) {
|
||
|
_stprintf(temp_string,"%s%s",node->GetName(),NameOptions.SuffixName);
|
||
|
node->SetName(temp_string);
|
||
|
}
|
||
|
|
||
|
if (NameOptions.AssignCollisionBits) {
|
||
|
|
||
|
W3DAppData2Struct * wdata = W3DAppData2Struct::Get_App_Data(node);
|
||
|
assert(wdata);
|
||
|
|
||
|
wdata->Enable_Physical_Collision(NameOptions.PhysicalCollision);
|
||
|
wdata->Enable_Projectile_Collision(NameOptions.ProjectileCollision);
|
||
|
wdata->Enable_Vis_Collision(NameOptions.VisCollision);
|
||
|
wdata->Enable_Camera_Collision(NameOptions.CameraCollision);
|
||
|
wdata->Enable_Vehicle_Collision(NameOptions.VehicleCollision);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::generate_material_names_for_node(INode * node)
|
||
|
{
|
||
|
if (MtlNameOptions.OnlyAffectSelected && !node->Selected()) {
|
||
|
return;
|
||
|
}
|
||
|
generate_material_names(node->GetMtl());
|
||
|
}
|
||
|
|
||
|
void W3DUtilityClass::generate_material_names(Mtl * mtl)
|
||
|
{
|
||
|
if (mtl == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// set the name of this material and increment the index
|
||
|
TCHAR newname[GenMtlNamesDialogClass::MAX_MATERIAL_NAME_LEN];
|
||
|
_stprintf(newname,"%s%03d",MtlNameOptions.RootName,WorkingNameIndex);
|
||
|
mtl->SetName(newname);
|
||
|
WorkingNameIndex++;
|
||
|
|
||
|
// recurse into children
|
||
|
if (mtl->IsMultiMtl()) {
|
||
|
for (int mi=0; mi<mtl->NumSubMtls(); mi++) {
|
||
|
generate_material_names(mtl->GetSubMtl(mi));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
W3DAppData0Struct * W3DUtilityClass::get_app_data_0(INode * node)
|
||
|
{
|
||
|
/*
|
||
|
** Try to get our AppData which has the export flags
|
||
|
*/
|
||
|
W3DAppData0Struct * wdata = NULL;
|
||
|
AppDataChunk * appdata = node->GetAppDataChunk(W3DUtilityClassID,UTILITY_CLASS_ID,0);
|
||
|
|
||
|
/*
|
||
|
** If there wasn't one, return NULL since this app data chunk is obsolete now.
|
||
|
** If there was one, get the data from it
|
||
|
*/
|
||
|
if (appdata) {
|
||
|
wdata = (W3DAppData0Struct *)(appdata->data);
|
||
|
}
|
||
|
|
||
|
return wdata;
|
||
|
}
|
||
|
|
||
|
|
||
|
W3DAppData1Struct * W3DUtilityClass::get_app_data_1(INode * node)
|
||
|
{
|
||
|
// Try to get our AppData which has the damage region
|
||
|
W3DAppData1Struct * wdata = NULL;
|
||
|
AppDataChunk * appdata = node->GetAppDataChunk(W3DUtilityClassID,UTILITY_CLASS_ID,1);
|
||
|
|
||
|
// If there wasn't one, add one. If there was one, get the data from it
|
||
|
if (appdata) {
|
||
|
wdata = (W3DAppData1Struct *)(appdata->data);
|
||
|
} else {
|
||
|
wdata = new W3DAppData1Struct;
|
||
|
node->AddAppDataChunk(W3DUtilityClassID,UTILITY_CLASS_ID,1,sizeof(W3DAppData1Struct),wdata);
|
||
|
|
||
|
appdata = node->GetAppDataChunk(W3DUtilityClassID,UTILITY_CLASS_ID,1);
|
||
|
assert(appdata);
|
||
|
}
|
||
|
|
||
|
return wdata;
|
||
|
}
|
||
|
|
||
|
|
||
|
W3DAppData2Struct * W3DUtilityClass::get_app_data_2(INode * node)
|
||
|
{
|
||
|
return W3DAppData2Struct::Get_App_Data(node);
|
||
|
}
|
||
|
|
||
|
|
||
|
W3DDazzleAppDataStruct * W3DUtilityClass::get_dazzle_app_data(INode * node)
|
||
|
{
|
||
|
return W3DDazzleAppDataStruct::Get_App_Data(node);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**********************************************************************************************
|
||
|
**
|
||
|
** Dialog procs for the W3DUtilityClass
|
||
|
**
|
||
|
**********************************************************************************************/
|
||
|
static BOOL CALLBACK _w3d_utility_tools_dlg_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
switch (msg) {
|
||
|
|
||
|
case WM_LBUTTONDOWN:
|
||
|
case WM_LBUTTONUP:
|
||
|
case WM_MOUSEMOVE:
|
||
|
TheW3DUtility.InterfacePtr->RollupMouseMessage(hWnd,msg,wParam,lParam);
|
||
|
break;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
{
|
||
|
switch (LOWORD(wParam))
|
||
|
{
|
||
|
/*
|
||
|
** Buttons
|
||
|
*/
|
||
|
case IDC_SELECT_GEOMETRY:
|
||
|
TheW3DUtility.Select_Geometry();
|
||
|
break;
|
||
|
|
||
|
case IDC_SELECT_HIERARCHY:
|
||
|
TheW3DUtility.Select_Hierarchy();
|
||
|
break;
|
||
|
|
||
|
case IDC_SELECT_ALPHA_MESHES:
|
||
|
TheW3DUtility.Select_Alpha();
|
||
|
break;
|
||
|
|
||
|
case IDC_SELECT_PHYSICAL:
|
||
|
TheW3DUtility.Select_Physical();
|
||
|
break;
|
||
|
|
||
|
case IDC_SELECT_PROJECTILE:
|
||
|
TheW3DUtility.Select_Projectile();
|
||
|
break;
|
||
|
|
||
|
case IDC_SELECT_VIS:
|
||
|
TheW3DUtility.Select_Vis();
|
||
|
break;
|
||
|
|
||
|
case IDC_COLLECTION_NAMES_GENERATE:
|
||
|
TheW3DUtility.generate_names();
|
||
|
TheW3DUtility.update_settings_controls();
|
||
|
break;
|
||
|
|
||
|
case IDC_MATERIAL_NAMES_GENERATE:
|
||
|
TheW3DUtility.generate_material_names();
|
||
|
TheW3DUtility.update_settings_controls();
|
||
|
break;
|
||
|
|
||
|
case IDC_LOD_EXTENSION_GENERATE:
|
||
|
TheW3DUtility.generate_lod_extensions();
|
||
|
TheW3DUtility.update_settings_controls();
|
||
|
break;
|
||
|
|
||
|
case IDC_EXPORT_STANDARD_MATERIALS:
|
||
|
TheW3DUtility.export_with_standard_materials();
|
||
|
break;
|
||
|
|
||
|
case IDC_CREATE_SETTINGS_FLOATER:
|
||
|
TheW3DUtility.create_floater();
|
||
|
break;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/**********************************************************************************************
|
||
|
**
|
||
|
** SettingsFormClass Implementation
|
||
|
** NOTE: When you use the _settings_form_dlg_proc, a SettingsFormClass will automatically
|
||
|
** be allocated and attached to the dialog. You can cause all of the active forms to
|
||
|
** refresh their status by calling Update_All_Instances. The forms will be destroyed when
|
||
|
** the window is destroyed.
|
||
|
**
|
||
|
**********************************************************************************************/
|
||
|
SettingsFormClass * SettingsFormClass::ActiveList = NULL;
|
||
|
|
||
|
BOOL CALLBACK _settings_form_dlg_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
if (msg == WM_INITDIALOG) {
|
||
|
SettingsFormClass * form = new SettingsFormClass(hWnd);
|
||
|
::SetProp(hWnd,"SettingsFormClass",(HANDLE)form);
|
||
|
}
|
||
|
|
||
|
SettingsFormClass * form = (SettingsFormClass *)::GetProp(hWnd,"SettingsFormClass");
|
||
|
if (form) {
|
||
|
return form->Dialog_Proc(hWnd,msg,wParam,lParam);
|
||
|
} else {
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void _settings_form_selection_changed_callback(void * param,NotifyInfo * info)
|
||
|
{
|
||
|
((SettingsFormClass*)param)->Selection_Changed();
|
||
|
}
|
||
|
|
||
|
SettingsFormClass::SettingsFormClass(HWND hwnd) :
|
||
|
Hwnd(hwnd),
|
||
|
RegionSpin(NULL)
|
||
|
{
|
||
|
/*
|
||
|
** Link into the active list
|
||
|
*/
|
||
|
Next = ActiveList;
|
||
|
ActiveList = this;
|
||
|
|
||
|
/*
|
||
|
** Register with MAX
|
||
|
*/
|
||
|
::RegisterNotification(_settings_form_selection_changed_callback, this, NOTIFY_SELECTIONSET_CHANGED);
|
||
|
}
|
||
|
|
||
|
SettingsFormClass::~SettingsFormClass(void)
|
||
|
{
|
||
|
/*
|
||
|
** Unregister from MAX
|
||
|
*/
|
||
|
::UnRegisterNotification(_settings_form_selection_changed_callback, this, NOTIFY_SELECTIONSET_CHANGED);
|
||
|
|
||
|
/*
|
||
|
** Unlink from the active list
|
||
|
*/
|
||
|
if (ActiveList == this) {
|
||
|
ActiveList = Next;
|
||
|
} else {
|
||
|
|
||
|
SettingsFormClass * prev = ActiveList;
|
||
|
SettingsFormClass * cur = ActiveList->Next;
|
||
|
|
||
|
while ((cur != this) && (cur != NULL)) {
|
||
|
cur = cur->Next;
|
||
|
prev = prev->Next;
|
||
|
}
|
||
|
|
||
|
assert(cur == this);
|
||
|
if (cur == this) {
|
||
|
prev->Next = cur->Next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Hwnd = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
void SettingsFormClass::Update_All_Instances(void)
|
||
|
{
|
||
|
if (ActiveList == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Build a list of the selected nodes
|
||
|
*/
|
||
|
INodeListClass node_list( ::GetCOREInterface()->GetRootNode(),
|
||
|
::GetCOREInterface()->GetTime(),
|
||
|
&_INodeFilter );
|
||
|
|
||
|
/*
|
||
|
** Update all settings forms
|
||
|
*/
|
||
|
SettingsFormClass * form = ActiveList;
|
||
|
while (form != NULL) {
|
||
|
form->Update_Controls(&node_list);
|
||
|
form = form->Next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void SettingsFormClass::Init(void)
|
||
|
{
|
||
|
// Initialize the contents of the dazzle combo
|
||
|
// Reset the dazzle combo
|
||
|
HWND dazzle_combo = GetDlgItem(Hwnd,IDC_DAZZLE_COMBO);
|
||
|
assert(dazzle_combo != NULL);
|
||
|
SendMessage(dazzle_combo,CB_RESETCONTENT,0,0);
|
||
|
|
||
|
// Load the section of Dazzle.INI that defines all of the types. The windows function
|
||
|
// that I'm using here, reads in a NULL-terminated string for each entry in the section. Each
|
||
|
// string is of the form 'key=value'. Based on my testing, it appears that windows removes any white
|
||
|
// space before or after the equal sign as well.
|
||
|
char dllpath[_MAX_PATH];
|
||
|
::GetModuleFileName(AppInstance,dllpath,sizeof(dllpath));
|
||
|
char * last_slash = strrchr(dllpath,'\\');
|
||
|
last_slash++;
|
||
|
strcpy(last_slash,DAZZLE_SETTINGS_FILENAME);
|
||
|
|
||
|
char * dazzle_types_buffer = new char[DAZZLE_SECTION_BUFFERSIZE]; // max size of a section for Win95
|
||
|
|
||
|
::GetPrivateProfileSection( DAZZLE_TYPES_SECTION, dazzle_types_buffer, DAZZLE_SECTION_BUFFERSIZE, dllpath);
|
||
|
|
||
|
// Now we need to handle each string in the section buffer; skipping the 'key=' and adding
|
||
|
// the dazzle type name into the combo box.
|
||
|
char * entry = dazzle_types_buffer;
|
||
|
if (entry != NULL) {
|
||
|
while (*entry != NULL) {
|
||
|
entry = strchr(entry,'=');
|
||
|
if (entry != NULL) {
|
||
|
entry++;
|
||
|
::SendMessage(dazzle_combo,CB_ADDSTRING,0,(LPARAM)entry);
|
||
|
entry += strlen(entry) + 1;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
::SendMessage(dazzle_combo,CB_ADDSTRING,0,(LPARAM)"Default");
|
||
|
}
|
||
|
|
||
|
::SendMessage(dazzle_combo,CB_SETCURSEL,(WPARAM)0,0);
|
||
|
|
||
|
delete dazzle_types_buffer;
|
||
|
|
||
|
/*
|
||
|
** Setup the damage region spinner control.
|
||
|
*/
|
||
|
RegionSpin = SetupIntSpinner
|
||
|
(
|
||
|
Hwnd,
|
||
|
IDC_DAMREG_INDEX_SPIN,
|
||
|
IDC_DAMREG_INDEX_EDIT,
|
||
|
NO_DAMAGE_REGION, MAX_DAMAGE_REGIONS-1, NO_DAMAGE_REGION
|
||
|
);
|
||
|
|
||
|
}
|
||
|
|
||
|
void SettingsFormClass::Destroy(void)
|
||
|
{
|
||
|
ReleaseISpinner(RegionSpin);
|
||
|
RegionSpin = NULL;
|
||
|
}
|
||
|
|
||
|
bool SettingsFormClass::Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
|
||
|
{
|
||
|
int check;
|
||
|
|
||
|
switch (message) {
|
||
|
case WM_INITDIALOG:
|
||
|
Init();
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
Destroy();
|
||
|
delete this;
|
||
|
break;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
{
|
||
|
/*
|
||
|
** handle the tri-state checkboxes.
|
||
|
** MAKE SURE YOU PUT ANY NEW CHECKBOX ID's IN HERE!!!
|
||
|
*/
|
||
|
int control_id = LOWORD(wParam);
|
||
|
if ( (control_id == IDC_HIERARCHY_CHECK) ||
|
||
|
(control_id == IDC_GEOMETRY_CHECK) ||
|
||
|
(control_id == IDC_GEOMETRY_HIDE) ||
|
||
|
(control_id == IDC_GEOMETRY_TWO_SIDED) ||
|
||
|
(control_id == IDC_GEOMETRY_ZNORMALS) ||
|
||
|
(control_id == IDC_GEOMETRY_VERTEX_ALPHA) ||
|
||
|
(control_id == IDC_GEOMETRY_CAST_SHADOW) ||
|
||
|
(control_id == IDC_GEOMETRY_SHATTERABLE) ||
|
||
|
(control_id == IDC_GEOMETRY_NPATCH) ||
|
||
|
(control_id == IDC_COLLISION_PHYSICAL) ||
|
||
|
(control_id == IDC_COLLISION_PROJECTILE) ||
|
||
|
(control_id == IDC_COLLISION_VIS) ||
|
||
|
(control_id == IDC_COLLISION_CAMERA) ||
|
||
|
(control_id == IDC_COLLISION_VEHICLE))
|
||
|
{
|
||
|
check = !SendDlgItemMessage(hWnd,LOWORD(wParam),BM_GETCHECK,0,0L);
|
||
|
SendDlgItemMessage(hWnd,LOWORD(wParam),BM_SETCHECK,check,0L);
|
||
|
}
|
||
|
|
||
|
INodeListClass node_list( ::GetCOREInterface()->GetRootNode(),
|
||
|
::GetCOREInterface()->GetTime(),
|
||
|
&_INodeFilter );
|
||
|
|
||
|
|
||
|
switch (LOWORD(wParam))
|
||
|
{
|
||
|
/*
|
||
|
** Tri-State Checkboxes, make sure that the ID of all checkboxes is present
|
||
|
** in the 'if' statement above!
|
||
|
*/
|
||
|
case IDC_HIERARCHY_CHECK:
|
||
|
W3DUtilityClass::set_hierarchy_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_CHECK:
|
||
|
W3DUtilityClass::set_geometry_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_HIDE:
|
||
|
W3DUtilityClass::enable_hidden_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_TWO_SIDED:
|
||
|
W3DUtilityClass::enable_two_sided_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_ZNORMALS:
|
||
|
W3DUtilityClass::enable_znormals_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_VERTEX_ALPHA:
|
||
|
W3DUtilityClass::enable_vertex_alpha_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_CAST_SHADOW:
|
||
|
W3DUtilityClass::enable_shadow_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_SHATTERABLE:
|
||
|
W3DUtilityClass::enable_shatterable_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_NPATCH:
|
||
|
W3DUtilityClass::enable_npatches_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_COLLISION_PHYSICAL:
|
||
|
W3DUtilityClass::enable_physical_collision_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_COLLISION_PROJECTILE:
|
||
|
W3DUtilityClass::enable_projectile_collision_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_COLLISION_VIS:
|
||
|
W3DUtilityClass::enable_vis_collision_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_COLLISION_CAMERA:
|
||
|
W3DUtilityClass::enable_camera_collision_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
case IDC_COLLISION_VEHICLE:
|
||
|
W3DUtilityClass::enable_vehicle_collision_in_all_selected(&node_list,check == BST_CHECKED);
|
||
|
break;
|
||
|
|
||
|
/*
|
||
|
** Radio buttons for the Geometry type
|
||
|
*/
|
||
|
case IDC_GEOMETRY_NORMAL:
|
||
|
W3DUtilityClass::set_geometry_type_in_all_selected(&node_list,W3DAppData2Struct::GEO_TYPE_NORMAL_MESH);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_CAMERA_ALIGNED:
|
||
|
W3DUtilityClass::set_geometry_type_in_all_selected(&node_list,W3DAppData2Struct::GEO_TYPE_CAMERA_ALIGNED);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_CAMERA_ORIENTED:
|
||
|
W3DUtilityClass::set_geometry_type_in_all_selected(&node_list,W3DAppData2Struct::GEO_TYPE_CAMERA_ORIENTED);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_NULL:
|
||
|
W3DUtilityClass::set_geometry_type_in_all_selected(&node_list,W3DAppData2Struct::GEO_TYPE_NULL);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_AABOX:
|
||
|
W3DUtilityClass::set_geometry_type_in_all_selected(&node_list,W3DAppData2Struct::GEO_TYPE_AABOX);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_OBBOX:
|
||
|
W3DUtilityClass::set_geometry_type_in_all_selected(&node_list,W3DAppData2Struct::GEO_TYPE_OBBOX);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_AGGREGATE:
|
||
|
W3DUtilityClass::set_geometry_type_in_all_selected(&node_list,W3DAppData2Struct::GEO_TYPE_AGGREGATE);
|
||
|
break;
|
||
|
|
||
|
case IDC_GEOMETRY_DAZZLE:
|
||
|
W3DUtilityClass::set_geometry_type_in_all_selected(&node_list,W3DAppData2Struct::GEO_TYPE_DAZZLE);
|
||
|
break;
|
||
|
|
||
|
/*
|
||
|
** Dazzle type setting. Whenever the user changes the selected dazzle type, apply
|
||
|
** the new setting to all selected nodes.
|
||
|
*/
|
||
|
case IDC_DAZZLE_COMBO:
|
||
|
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||
|
|
||
|
HWND dazzle_combo = GetDlgItem(hWnd,IDC_DAZZLE_COMBO);
|
||
|
if (dazzle_combo != NULL) {
|
||
|
|
||
|
char dazzle_type[128];
|
||
|
int cursel = ::SendMessage(dazzle_combo,CB_GETCURSEL,0,0);
|
||
|
int len = ::SendMessage(dazzle_combo,CB_GETLBTEXTLEN,cursel,0);
|
||
|
if (len < 128) {
|
||
|
::SendMessage(dazzle_combo,CB_GETLBTEXT,(WPARAM)cursel,(LPARAM)dazzle_type);
|
||
|
W3DUtilityClass::set_dazzle_type_in_all_selected(&node_list,dazzle_type);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Spinners
|
||
|
*/
|
||
|
case CC_SPINNER_CHANGE:
|
||
|
{
|
||
|
INodeListClass node_list( ::GetCOREInterface()->GetRootNode(),
|
||
|
::GetCOREInterface()->GetTime(),
|
||
|
&_INodeFilter );
|
||
|
|
||
|
W3DUtilityClass::set_region_in_all_selected(&node_list,RegionSpin->GetIVal());
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Max Custom Edit boxes
|
||
|
*/
|
||
|
case WM_CUSTEDIT_ENTER:
|
||
|
{
|
||
|
INodeListClass node_list( ::GetCOREInterface()->GetRootNode(),
|
||
|
::GetCOREInterface()->GetTime(),
|
||
|
&_INodeFilter );
|
||
|
|
||
|
ICustEdit * edit_ctrl = GetICustEdit(GetDlgItem(hWnd,wParam));
|
||
|
if (wParam == IDC_OBJ_NAME) {
|
||
|
if (edit_ctrl && node_list.Num_Nodes() == 1) {
|
||
|
char buffer[64];
|
||
|
edit_ctrl->GetText(buffer,sizeof(buffer));
|
||
|
node_list[0]->SetName(buffer);
|
||
|
Update_All_Instances();
|
||
|
}
|
||
|
}
|
||
|
ReleaseICustEdit(edit_ctrl);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
default:
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void SettingsFormClass::Selection_Changed(void)
|
||
|
{
|
||
|
INodeListClass node_list( ::GetCOREInterface()->GetRootNode(),
|
||
|
::GetCOREInterface()->GetTime(),
|
||
|
&_INodeFilter );
|
||
|
|
||
|
Update_Controls(&node_list);
|
||
|
}
|
||
|
|
||
|
void SettingsFormClass::Update_Controls(INodeListClass * node_list)
|
||
|
{
|
||
|
/*
|
||
|
** Update name of currently selected object
|
||
|
** "Multiple" if more than one, "None" if no selected objs...
|
||
|
*/
|
||
|
ICustEdit * edit_ctrl = GetICustEdit(GetDlgItem(Hwnd,IDC_OBJ_NAME));
|
||
|
if (edit_ctrl != NULL) {
|
||
|
if (node_list->Num_Nodes() == 0) {
|
||
|
edit_ctrl->Enable(FALSE);
|
||
|
edit_ctrl->SetText(Get_String(IDS_NO_OBJECT));
|
||
|
} else if (node_list->Num_Nodes() == 1) {
|
||
|
edit_ctrl->Enable(TRUE);
|
||
|
edit_ctrl->SetText((*node_list)[0]->GetName());
|
||
|
} else {
|
||
|
edit_ctrl->Enable(FALSE);
|
||
|
edit_ctrl->SetText(Get_String(IDS_MULTIPLE_OBJECTS));
|
||
|
}
|
||
|
|
||
|
ReleaseICustEdit(edit_ctrl);
|
||
|
}
|
||
|
|
||
|
if (node_list->Num_Nodes() == 0) {
|
||
|
Disable_Controls();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
W3DUtilityClass::NodeStatesStruct ns;
|
||
|
W3DUtilityClass::eval_node_states(node_list,&ns);
|
||
|
|
||
|
/*
|
||
|
** Enable hierarchy and geometry checks since they are always available
|
||
|
*/
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_HIERARCHY_CHECK),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_CHECK),TRUE);
|
||
|
|
||
|
/*
|
||
|
** Enable/Disable the geometry controls
|
||
|
*/
|
||
|
if (ns.ExportGeometry == 1) {
|
||
|
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_CAMERA_ALIGNED),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_CAMERA_ORIENTED),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_NORMAL),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_NULL),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_AABOX),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_OBBOX),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_AGGREGATE),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_DAZZLE),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_HIDE),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_TWO_SIDED),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_ZNORMALS),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_VERTEX_ALPHA),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_CAST_SHADOW),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_SHATTERABLE),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_NPATCH),TRUE);
|
||
|
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_PHYSICAL),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_PROJECTILE),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_VIS),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_CAMERA),TRUE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_VEHICLE),TRUE);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_CAMERA_ALIGNED),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_CAMERA_ORIENTED),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_NORMAL),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_NULL),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_AABOX),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_OBBOX),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_AGGREGATE),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_DAZZLE),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_HIDE),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_TWO_SIDED),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_ZNORMALS),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_VERTEX_ALPHA),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_CAST_SHADOW),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_SHATTERABLE),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_NPATCH),FALSE);
|
||
|
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_PHYSICAL),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_PROJECTILE),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_VIS),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_CAMERA),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_VEHICLE),FALSE);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Set the checks based on the nodes states:
|
||
|
** no check - none of the selected nodes had this setting
|
||
|
** check - all of the selected nodes had this setting
|
||
|
** grey check - some of the selected nodes had this setting
|
||
|
*/
|
||
|
SendDlgItemMessage(Hwnd,IDC_HIERARCHY_CHECK,BM_SETCHECK,ns.ExportHierarchy,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_GEOMETRY_CHECK,BM_SETCHECK,ns.ExportGeometry,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_GEOMETRY_HIDE,BM_SETCHECK,ns.GeometryHidden,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_GEOMETRY_TWO_SIDED,BM_SETCHECK,ns.GeometryTwoSided,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_GEOMETRY_ZNORMALS,BM_SETCHECK,ns.GeometryZNormals,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_GEOMETRY_VERTEX_ALPHA,BM_SETCHECK,ns.GeometryVertexAlpha,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_GEOMETRY_CAST_SHADOW,BM_SETCHECK,ns.GeometryCastShadow,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_GEOMETRY_SHATTERABLE,BM_SETCHECK,ns.GeometryShatterable,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_GEOMETRY_NPATCH,BM_SETCHECK,ns.GeometryNPatch,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_COLLISION_PHYSICAL,BM_SETCHECK,ns.CollisionPhysical,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_COLLISION_PROJECTILE,BM_SETCHECK,ns.CollisionProjectile,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_COLLISION_VIS,BM_SETCHECK,ns.CollisionVis,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_COLLISION_CAMERA,BM_SETCHECK,ns.CollisionCamera,0L);
|
||
|
SendDlgItemMessage(Hwnd,IDC_COLLISION_VEHICLE,BM_SETCHECK,ns.CollisionVehicle,0L);
|
||
|
|
||
|
/*
|
||
|
** The damage region spinner should only be enabled if
|
||
|
** Export Hierarchy is checked for all selected nodes.
|
||
|
*/
|
||
|
BOOL spinner_enable = false;
|
||
|
if (ns.ExportHierarchy == 1)
|
||
|
{
|
||
|
if (ns.DamageRegion != MAX_DAMAGE_REGIONS)
|
||
|
{
|
||
|
// Show the damage region in the spinner.
|
||
|
RegionSpin->SetIndeterminate(FALSE);
|
||
|
RegionSpin->SetValue(ns.DamageRegion, FALSE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// The selected objects aren't all in the same region.
|
||
|
RegionSpin->SetIndeterminate(TRUE);
|
||
|
}
|
||
|
|
||
|
spinner_enable = true;
|
||
|
}
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_DAMREG_INDEX_EDIT),spinner_enable);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_DAMREG_INDEX_SPIN),spinner_enable);
|
||
|
|
||
|
/*
|
||
|
** The dazzle combo box should only be enabled if
|
||
|
** Export Geometry, and geometry type dazzle is set for all
|
||
|
** selected nodes.
|
||
|
*/
|
||
|
bool dazzle_combo_enable = false;
|
||
|
if (ns.ExportGeometry == 1) {
|
||
|
if (ns.DazzleCount == node_list->Num_Nodes()) {
|
||
|
dazzle_combo_enable = true;
|
||
|
}
|
||
|
}
|
||
|
HWND dazzle_combo = GetDlgItem(Hwnd,IDC_DAZZLE_COMBO);
|
||
|
EnableWindow(dazzle_combo,dazzle_combo_enable);
|
||
|
int selindex = ::SendMessage(dazzle_combo,CB_FINDSTRING,(WPARAM)0,(LPARAM)ns.DazzleType);
|
||
|
if (selindex != CB_ERR) {
|
||
|
::SendMessage(dazzle_combo,CB_SETCURSEL,(WPARAM)selindex,(LPARAM)0);
|
||
|
} else {
|
||
|
::SendMessage(dazzle_combo,CB_SETCURSEL,(WPARAM)0,(LPARAM)0);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Set any radio buttons present
|
||
|
*/
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_CAMERA_ALIGNED,(ns.GeometryCameraAligned ? BST_CHECKED : BST_UNCHECKED));
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_CAMERA_ORIENTED,(ns.GeometryCameraOriented ? BST_CHECKED : BST_UNCHECKED));
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_NORMAL,(ns.GeometryNormal ? BST_CHECKED : BST_UNCHECKED));
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_NULL,(ns.GeometryNull ? BST_CHECKED : BST_UNCHECKED));
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_AABOX,(ns.GeometryAABox ? BST_CHECKED : BST_UNCHECKED));
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_OBBOX,(ns.GeometryOBBox ? BST_CHECKED : BST_UNCHECKED));
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_AGGREGATE,(ns.GeometryAggregate ? BST_CHECKED : BST_UNCHECKED));
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_DAZZLE,(ns.GeometryDazzle ? BST_CHECKED : BST_UNCHECKED));
|
||
|
}
|
||
|
|
||
|
|
||
|
void SettingsFormClass::Disable_Controls(void)
|
||
|
{
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_OBJ_NAME),FALSE);
|
||
|
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_HIERARCHY_CHECK),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_CHECK),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_DAMREG_INDEX_EDIT),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_DAMREG_INDEX_SPIN),FALSE);
|
||
|
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_NORMAL),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_CAMERA_ALIGNED),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_CAMERA_ORIENTED),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_AABOX),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_OBBOX),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_NULL),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_AGGREGATE),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_DAZZLE),FALSE);
|
||
|
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_HIDE),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_TWO_SIDED),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_ZNORMALS),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_VERTEX_ALPHA),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_CAST_SHADOW),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_SHATTERABLE),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_GEOMETRY_NPATCH),FALSE);
|
||
|
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_PHYSICAL),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_PROJECTILE),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_VIS),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_CAMERA),FALSE);
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_COLLISION_VEHICLE),FALSE);
|
||
|
|
||
|
EnableWindow(GetDlgItem(Hwnd,IDC_DAZZLE_COMBO),FALSE);
|
||
|
|
||
|
CheckDlgButton(Hwnd,IDC_HIERARCHY_CHECK,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_CHECK,BST_UNCHECKED);
|
||
|
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_CAMERA_ALIGNED,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_CAMERA_ORIENTED,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_NORMAL,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_AABOX,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_OBBOX,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_NULL,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_AGGREGATE,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_DAZZLE,BST_UNCHECKED);
|
||
|
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_HIDE,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_TWO_SIDED,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_ZNORMALS,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_VERTEX_ALPHA,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_CAST_SHADOW,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_SHATTERABLE,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_GEOMETRY_NPATCH,BST_UNCHECKED);
|
||
|
|
||
|
CheckDlgButton(Hwnd,IDC_COLLISION_PHYSICAL,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_COLLISION_PROJECTILE,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_COLLISION_VIS,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_COLLISION_CAMERA,BST_UNCHECKED);
|
||
|
CheckDlgButton(Hwnd,IDC_COLLISION_VEHICLE,BST_UNCHECKED);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
** Functions to access the W3D AppData of any INode.
|
||
|
*/
|
||
|
W3DAppData0Struct * GetW3DAppData0 (INode *node)
|
||
|
{
|
||
|
return TheW3DUtility.get_app_data_0(node);
|
||
|
}
|
||
|
|
||
|
W3DAppData1Struct * GetW3DAppData1 (INode *node)
|
||
|
{
|
||
|
return TheW3DUtility.get_app_data_1(node);
|
||
|
}
|
||
|
|
||
|
W3DAppData2Struct * GetW3DAppData2 (INode *node)
|
||
|
{
|
||
|
return TheW3DUtility.get_app_data_2(node);
|
||
|
}
|
||
|
|
||
|
W3DDazzleAppDataStruct * GetW3DDazzleAppData(INode *node)
|
||
|
{
|
||
|
return TheW3DUtility.get_dazzle_app_data(node);
|
||
|
}
|