/*
** 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 .
*/
/* $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
#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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; niNum_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; iNumberOfChildren(); 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; miNumSubMtls(); 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_indexGetSubMtl(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; miNumSubMtls(); 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);
}