416 lines
18 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Max2W3d *
* *
* $Archive:: /Commando/Code/Tools/max2w3d/w3dappdata.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 8/21/01 9:44a $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef W3DAPPDATA_H
#define W3DAPPDATA_H
#include <Max.h>
/*
** The W3DUtilityClass uses several app-data chunks to store user-options for INodes
** in the MAX scene. Below are the IDs for each app-data chunk type:
*/
#define W3D_APPDATA_0 0
#define W3D_APPDATA_1 1
#define W3D_APPDATA_2 2
#define W3D_DAZZLE_APPDATA 3
/*
** Classifying INodes for w3d exporting
**
** NOTE: Use these utility functions rather than going straight to the AppData
** structure!
**
** - There are bits stored in AppData for each node
** - These bits indicate wether something should be exported as hierarchy,
** geometry (and if so, what type of geometry: mesh, collision box, bitmap, etc)
**
** When we say something is "Hierarchy" that means its transform should be put
** into any hierarchy tree or motion being created. In some places I used
** the term "Bone" which means the same thing.
**
** When we say something is "Geometry" that means that the object will become
** some sort of render object (normal mesh, bitmap, collision mesh, etc)
**
*/
/*
** Either or both of these will return true for a given INode
*/
bool Is_Bone(INode * node);
bool Is_Geometry(INode * node);
/*
** Geometry Type:
** One of the following will return true if the given INode is
** to have its geometry exported
*/
bool Is_Normal_Mesh(INode * node);
bool Is_Camera_Aligned_Mesh(INode * node);
bool Is_Camera_Oriented_Mesh(INode * node);
bool Is_Collision_AABox(INode * node);
bool Is_Collision_OBBox(INode * node);
bool Is_Skin(INode * node);
bool Is_Shadow(INode * node);
bool Is_Null_Object(INode * node);
bool Is_Dazzle(INode * node);
bool Is_Aggregate(INode * node);
/*
** Collision Bits, any or all of these may return true for a given INode
*/
bool Is_Physical_Collision(INode * node);
bool Is_Projectile_Collision(INode * node);
bool Is_Vis_Collision(INode * node);
bool Is_Camera_Collision(INode * node);
bool Is_Vehicle_Collision(INode * node);
/*
** Miscellaneous settings
*/
bool Is_Hidden(INode * node);
bool Is_Two_Sided(INode * node);
bool Is_ZNormals(INode * node);
bool Is_Vertex_Alpha(INode * node);
bool Is_Shatterable(INode * node);
bool Is_NPatchable(INode * node);
/*
** Proxy support. If a node has a name which contains a ~ it is considered a
** proxy for an application defined named object. This overrides all other
** settings (in the future, we shouldn't do things this way!)
*/
inline bool Is_Proxy(INode &node)
{
return (::strchr (node.GetName (), '~') != NULL);
}
/*
** AJA 9/24/99
** NOTE: Whenever you add a new W3DAppDataStruct, you must add an accessor function
** to the bottom of this file. Then the WWScript.dlx project must be modified. That
** project implements an extension to the MAXScript language in the form of a function
** called "wwCopyAppData". The implementation of this wwCopyAppData function must be
** aware of the new W3DAppDataStruct. The modification is pretty straightfoward.
**
** The wwCopyAppData extension was added to MAXScript so that the data we define
** below can be preserve when a model is cloned (copy/instance/reference). What
** happens without using wwCopyAppData is that a new INode is created that contains
** a copy/instance/reference to the original mesh/bone in the source model. When
** this new INode is created, it has no app data. When the app data is examined later
** on, it gets the default values! That means all information concerning Export
** Geometry/Transform, mesh type, and damage region is lost. wwCopyAppData allows
** a script to duplicate a model INCLUDING all W3D app data, so that this information
** is preserved.
*/
/*
** The W3DAppData0Struct contains a bitfield. These #defines are
** used to interpret the bits.
** (gth) NOTE: AppData0 is now OBSOLETE!!! Use W3DAppData2Struct now.
*/
#define EXPORT_TYPE_MASK 0x000F
#define GEOMETRY_TYPE_MASK 0x01F0
#define COLLISION_TYPE_MASK 0xF000
#define EXPORT_BONE_FLAG 0x0001 // export a bone (transform) for this node
#define EXPORT_GEOMETRY_FLAG 0x0002 // export the geometry for this node
#define EXPORT_HIDDEN_FLAG 0x0004 // mesh should be hidden by default
#define EXPORT_TWO_SIDED_FLAG 0x0008 // mesh should be two sided
#define GEOMETRY_TYPE_CAMERA_ALIGNED 0x0010 // interpret this geometry as a camera-aligned mesh
#define GEOMETRY_TYPE_NORMAL_MESH 0x0020 // this is a normal mesh
#define GEOMETRY_TYPE_OBBOX 0x0030 // this is an oriented box (should have 8 verts, etc)
#define GEOMETRY_TYPE_AABOX 0x0040 // this is an axis aligned box
#define GEOMETRY_TYPE_CAMERA_ORIENTED 0x0050 // interpret this geometry as a camera-oriented mesh
#define GEOMETRY_TYPE_NULL 0x0100 // this is a null (for LOD)
#define EXPORT_CAST_SHADOW_FLAG 0x0200 // this mesh casts a shadow
#define EXPORT_VERTEX_ALPHA_FLAG 0x0400 // convert vertex colors to alpha
#define EXPORT_ZNORMALS_FLAG 0x0800 // force vertex normals to point along +z
#define COLLISION_TYPE_PHYSICAL 0x1000 // runtime engine performs physical collision against this mesh
#define COLLISION_TYPE_PROJECTILE 0x2000 // perform projectile collisions against this mesh
#define COLLISION_TYPE_VIS 0x4000 // perform vis group collisions against this mesh
#define DEFAULT_MESH_EXPORT_FLAGS (EXPORT_BONE_FLAG | EXPORT_GEOMETRY_FLAG | GEOMETRY_TYPE_NORMAL_MESH)
#define DEFAULT_EXPORT_FLAGS 0
/*
** W3D Utility AppData sub-type 0 (OBSOLETE!)
** ----------------------------------------------------
** The utility provides a right-click menu which allows
** the user to toggle the export flags.
** (gth) NOTE: AppData0 is now OBSOLETE!!! Use W3DAppData2Struct now.
*/
struct W3DAppData0Struct
{
W3DAppData0Struct(void) : ExportFlags(DEFAULT_EXPORT_FLAGS) {}
bool Is_Bone(void) { return (ExportFlags & EXPORT_BONE_FLAG) == EXPORT_BONE_FLAG; }
bool Is_Geometry(void) { return (ExportFlags & EXPORT_GEOMETRY_FLAG) == EXPORT_GEOMETRY_FLAG; }
bool Is_Normal_Mesh(void) { return (ExportFlags & GEOMETRY_TYPE_MASK) == GEOMETRY_TYPE_NORMAL_MESH; }
bool Is_Camera_Aligned_Mesh(void) { return (ExportFlags & GEOMETRY_TYPE_MASK) == GEOMETRY_TYPE_CAMERA_ALIGNED; }
bool Is_Camera_Oriented_Mesh(void) { return (ExportFlags & GEOMETRY_TYPE_MASK) == GEOMETRY_TYPE_CAMERA_ORIENTED; }
bool Is_Collision_AABox(void) { return (ExportFlags & GEOMETRY_TYPE_MASK) == GEOMETRY_TYPE_AABOX; }
bool Is_Collision_OBBox(void) { return (ExportFlags & GEOMETRY_TYPE_MASK) == GEOMETRY_TYPE_OBBOX; }
bool Is_Null(void) { return (ExportFlags & GEOMETRY_TYPE_MASK) == GEOMETRY_TYPE_NULL; }
bool Is_Physical_Collision(void) { return (ExportFlags & COLLISION_TYPE_PHYSICAL) == COLLISION_TYPE_PHYSICAL; }
bool Is_Projectile_Collision(void) { return (ExportFlags & COLLISION_TYPE_PROJECTILE) == COLLISION_TYPE_PROJECTILE; }
bool Is_Vis_Collision(void) { return (ExportFlags & COLLISION_TYPE_VIS) == COLLISION_TYPE_VIS; }
bool Is_Hidden(void) { return (ExportFlags & EXPORT_HIDDEN_FLAG) == EXPORT_HIDDEN_FLAG; }
bool Is_Two_Sided(void) { return (ExportFlags & EXPORT_TWO_SIDED_FLAG) == EXPORT_TWO_SIDED_FLAG; }
bool Is_Vertex_Alpha(void) { return (ExportFlags & EXPORT_VERTEX_ALPHA_FLAG) == EXPORT_VERTEX_ALPHA_FLAG; }
bool Is_ZNormals(void) { return (ExportFlags & EXPORT_ZNORMALS_FLAG) == EXPORT_ZNORMALS_FLAG; }
bool Is_Shadow(void) { return (ExportFlags & EXPORT_CAST_SHADOW_FLAG) == EXPORT_CAST_SHADOW_FLAG; }
unsigned short ExportFlags; // what was I thinking??? (gth)
};
/*
** W3D Utility AppData sub-type 1
** ----------------------------------------------------
** This AppData contains the damage region number for
** the current object.
*/
// Maximum number of damage regions on a model.
#define MAX_DAMAGE_REGIONS ((char)16)
// Value that represents no damage region.
#define NO_DAMAGE_REGION ((char)-1)
struct W3DAppData1Struct
{
W3DAppData1Struct(void) : DamageRegion(NO_DAMAGE_REGION) { }
/*
** NO_DAMAGE_REGION means the object isn't part of
** any damage region, 0 through MAX_DAMAGE_REGIONS-1
** are valid damage regions.
*/
char DamageRegion;
};
/*
** W3D Utility AppData sub-type 2
** ----------------------------------------------------
** This is an app-data struct that is meant to contain all
** of the w3d export options for an object in MAX. It
** replaces the old AppData sub-type 0. Call the static
** member functions in the class to get a pointer to
** the AppData2 struct hanging off any INode and automatically
** create one for you if there isn't already one...
*/
struct W3DAppData2Struct
{
W3DAppData2Struct(void);
W3DAppData2Struct(W3DAppData0Struct & olddata);
void Init_With_Mesh_Defaults(void);
void Init_With_Other_Defaults(void);
void Init_From_AppData0(W3DAppData0Struct & olddata);
void Update_Version(void);
enum GeometryTypeEnum
{
GEO_TYPE_CAMERA_ALIGNED = 0x00000001, // Geometry types are mutually exclusive
GEO_TYPE_NORMAL_MESH = 0x00000002,
GEO_TYPE_OBBOX = 0x00000003,
GEO_TYPE_AABOX = 0x00000004,
GEO_TYPE_CAMERA_ORIENTED = 0x00000005,
GEO_TYPE_NULL = 0x00000006,
GEO_TYPE_DAZZLE = 0x00000007,
GEO_TYPE_AGGREGATE = 0x00000008,
};
/*
** Read Access
*/
bool Is_Bone(void) const { return (ExportFlags & EXPORT_TRANSFORM) == EXPORT_TRANSFORM; }
bool Is_Geometry(void) const { return (ExportFlags & EXPORT_GEOMETRY) == EXPORT_GEOMETRY; }
int Get_Geometry_Type(void) const { return GeometryType; }
bool Is_Normal_Mesh(void) const { return GeometryType == GEO_TYPE_NORMAL_MESH; }
bool Is_Camera_Aligned_Mesh(void) const { return GeometryType == GEO_TYPE_CAMERA_ALIGNED; }
bool Is_Camera_Oriented_Mesh(void) const { return GeometryType == GEO_TYPE_CAMERA_ORIENTED; }
bool Is_Collision_AABox(void) const { return GeometryType == GEO_TYPE_AABOX; }
bool Is_Collision_OBBox(void) const { return GeometryType == GEO_TYPE_OBBOX; }
bool Is_Null(void) const { return GeometryType == GEO_TYPE_NULL; }
bool Is_Dazzle(void) const { return GeometryType == GEO_TYPE_DAZZLE; }
bool Is_Hidden_Enabled(void) const { return (GeometryFlags & GEOMETRY_FLAG_HIDDEN) == GEOMETRY_FLAG_HIDDEN; }
bool Is_Two_Sided_Enabled(void) const { return (GeometryFlags & GEOMETRY_FLAG_TWO_SIDED) == GEOMETRY_FLAG_TWO_SIDED; }
bool Is_Vertex_Alpha_Enabled(void) const { return (GeometryFlags & GEOMETRY_FLAG_VERTEX_ALPHA) == GEOMETRY_FLAG_VERTEX_ALPHA; }
bool Is_ZNormals_Enabled(void) const { return (GeometryFlags & GEOMETRY_FLAG_ZNORMALS) == GEOMETRY_FLAG_ZNORMALS; }
bool Is_Shadow_Enabled(void) const { return (GeometryFlags & GEOMETRY_FLAG_CAST_SHADOW) == GEOMETRY_FLAG_CAST_SHADOW; }
bool Is_Shatterable_Enabled(void) const { return (GeometryFlags & GEOMETRY_FLAG_SHATTERABLE) == GEOMETRY_FLAG_SHATTERABLE; }
bool Is_NPatchable_Enabled(void) const { return (GeometryFlags & GEOMETRY_FLAG_NPATCHABLE) == GEOMETRY_FLAG_NPATCHABLE; }
bool Is_Physical_Collision_Enabled(void) const { return (CollisionFlags & COLLISION_FLAG_PHYSICAL) == COLLISION_FLAG_PHYSICAL; }
bool Is_Projectile_Collision_Enabled(void) const { return (CollisionFlags & COLLISION_FLAG_PROJECTILE) == COLLISION_FLAG_PROJECTILE; }
bool Is_Vis_Collision_Enabled(void) const { return (CollisionFlags & COLLISION_FLAG_VIS) == COLLISION_FLAG_VIS; }
bool Is_Camera_Collision_Enabled(void) const { return (CollisionFlags & COLLISION_FLAG_CAMERA) == COLLISION_FLAG_CAMERA; }
bool Is_Vehicle_Collision_Enabled(void) const { return (CollisionFlags & COLLISION_FLAG_VEHICLE) == COLLISION_FLAG_VEHICLE; }
/*
** Write Access
*/
void Enable_Export_Transform(bool onoff) { if (onoff) { ExportFlags |= EXPORT_TRANSFORM; } else { ExportFlags &= ~EXPORT_TRANSFORM; } }
void Enable_Export_Geometry(bool onoff) { if (onoff) { ExportFlags |= EXPORT_GEOMETRY; } else { ExportFlags &= ~EXPORT_GEOMETRY; } }
void Set_Geometry_Type(GeometryTypeEnum type) { GeometryType = (unsigned int)type; }
void Enable_Hidden(bool onoff) { if (onoff) { GeometryFlags |= GEOMETRY_FLAG_HIDDEN; } else { GeometryFlags &= ~GEOMETRY_FLAG_HIDDEN; } }
void Enable_Two_Sided(bool onoff) { if (onoff) { GeometryFlags |= GEOMETRY_FLAG_TWO_SIDED; } else { GeometryFlags &= ~GEOMETRY_FLAG_TWO_SIDED; } }
void Enable_Shadow(bool onoff) { if (onoff) { GeometryFlags |= GEOMETRY_FLAG_CAST_SHADOW; } else { GeometryFlags &= ~GEOMETRY_FLAG_CAST_SHADOW; } }
void Enable_Vertex_Alpha(bool onoff) { if (onoff) { GeometryFlags |= GEOMETRY_FLAG_VERTEX_ALPHA; } else { GeometryFlags &= ~GEOMETRY_FLAG_VERTEX_ALPHA; } }
void Enable_ZNormals(bool onoff) { if (onoff) { GeometryFlags |= GEOMETRY_FLAG_ZNORMALS; } else { GeometryFlags &= ~GEOMETRY_FLAG_ZNORMALS; } }
void Enable_Shatterable(bool onoff) { if (onoff) { GeometryFlags |= GEOMETRY_FLAG_SHATTERABLE; } else { GeometryFlags &= ~GEOMETRY_FLAG_SHATTERABLE; } }
void Enable_NPatchable(bool onoff) { if (onoff) { GeometryFlags |= GEOMETRY_FLAG_NPATCHABLE; } else { GeometryFlags &= ~GEOMETRY_FLAG_NPATCHABLE; } }
void Enable_Physical_Collision(bool onoff) { if (onoff) { CollisionFlags |= COLLISION_FLAG_PHYSICAL; } else { CollisionFlags &= ~COLLISION_FLAG_PHYSICAL; } }
void Enable_Projectile_Collision(bool onoff) { if (onoff) { CollisionFlags |= COLLISION_FLAG_PROJECTILE; } else { CollisionFlags &= ~COLLISION_FLAG_PROJECTILE; } }
void Enable_Vis_Collision(bool onoff) { if (onoff) { CollisionFlags |= COLLISION_FLAG_VIS; } else { CollisionFlags &= ~COLLISION_FLAG_VIS; } }
void Enable_Camera_Collision(bool onoff) { if (onoff) { CollisionFlags |= COLLISION_FLAG_CAMERA; } else { CollisionFlags &= ~COLLISION_FLAG_CAMERA; } }
void Enable_Vehicle_Collision(bool onoff) { if (onoff) { CollisionFlags |= COLLISION_FLAG_VEHICLE; } else { CollisionFlags &= ~COLLISION_FLAG_VEHICLE; } }
/*
** Comparison
*/
bool operator == (const W3DAppData2Struct & that);
bool operator != (const W3DAppData2Struct & that) { return !(*this == that); }
bool Geometry_Options_Match(const W3DAppData2Struct & that);
/*
** Get the W3DAppData2Struct for a given INode and create one if
** there isn't already one.
*/
static W3DAppData2Struct * Get_App_Data(INode * node,bool create_if_missing = true);
protected:
void Set_Version(int ver) { ExportFlags &= ~VERSION_MASK; ExportFlags |= (ver<<VERSION_SHIFT); }
int Get_Version(void) { return (ExportFlags & VERSION_MASK)>>VERSION_SHIFT; }
enum ExportFlagsEnum
{
EXPORT_TRANSFORM = 0x00000001, // Export flags bit-field
EXPORT_GEOMETRY = 0x00000002,
VERSION_MASK = 0xFFFF0000, // upper 16bits is version number.
VERSION_SHIFT = 16,
};
enum GeometryFlagsEnum
{
GEOMETRY_FLAG_HIDDEN = 0x00000001, // Geometry Flags bitfield
GEOMETRY_FLAG_TWO_SIDED = 0x00000002,
GEOMETRY_FLAG_CAST_SHADOW = 0x00000004,
GEOMETRY_FLAG_VERTEX_ALPHA = 0x00000008,
GEOMETRY_FLAG_ZNORMALS = 0x00000010,
GEOMETRY_FLAG_SHATTERABLE = 0x00000020,
GEOMETRY_FLAG_NPATCHABLE = 0x00000040,
};
enum CollisionFlagsEnum
{
COLLISION_FLAG_PHYSICAL = 0x00000001,
COLLISION_FLAG_PROJECTILE = 0x00000002,
COLLISION_FLAG_VIS = 0x00000004,
COLLISION_FLAG_CAMERA = 0x00000008,
COLLISION_FLAG_VEHICLE = 0x00000010,
};
unsigned int ExportFlags;
unsigned int GeometryType;
unsigned int GeometryFlags;
unsigned int CollisionFlags;
// future expansion, initialized to zeros
unsigned int UnUsed[4];
};
/*
** W3D Utility Dazzle App Data
** ----------------------------------------------------
** This app-data struct is used to contain parameters
** specific to dazzle render objects. It currently only
** contains a type name which is limited to 128 characters
** and some padding variables for future use.
*/
struct W3DDazzleAppDataStruct
{
/*
** Constructor, zeros everything, then initializes DazzleType to "DEFAULT"
*/
W3DDazzleAppDataStruct(void);
/*
** Get the W3DAppData2Struct for a given INode and create one if
** there isn't already one.
*/
static W3DDazzleAppDataStruct * Get_App_Data(INode * node,bool create_if_missing = true);
/*
** Members
*/
unsigned int UnUsed[4];
char DazzleType[128];
};
#endif