| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477 |
- /*
- ** Command & Conquer Generals(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 : Buccaneer Bay *
- * *
- * File name : AlphaModifier.cpp *
- * *
- * Programmer : Mike Lytle *
- * *
- * Start date : 11/1/1999 *
- * *
- * Last update : 11/1/1999 *
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "AlphaModifier.h"
- enum Alpha_Messages
- {
- AM_NOTHING,
- AM_UPDATE_DATA,
- AM_INITIALIZE,
- AM_BOX_CHECKED,
- };
- enum Dialog_Controls
- {
- DL_EDIT_VALUE,
- DL_FIND_CHECK_BOX,
- };
- void AlphaModifierClass::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node)
- {
- if (!os->obj->IsSubClassOf(triObjectClassID))
- {
- return;
- }
-
- // Get a mesh from input object
- TriObject *object = (TriObject*)os->obj;
- Mesh *mesh = &object->mesh;
- assert(mesh);
- int numVert = mesh->getNumVerts();
- int i = 0;
- float *vdata = NULL;
- // Get parameters from pblock
- float sparam = 0.0f;
- Interval valid = LocalValidity(t);
- int pass = 1;
- pblock->GetValue(DL_EDIT_VALUE, t, sparam, valid);
- // If needed a control could be put into the dialog box to specify which
- // pass to apply the alpha values to. At this time, it was decided to
- // not implement this because of the complexity to the artist and the
- // performance issues in game.
- //pblock->GetValue(DL_EDIT_PASS, t, pass, valid);
- // Start from 0.
- pass -= 1;
- assert(pass >= 0);
- // Use a channel for each pass.
- vdata = mesh->vertexFloat(ALPHA_VERTEX_CHANNEL + pass);
- if (!vdata)
- {
- // Turn on the channel for vertex alpha support.
- mesh->setVDataSupport(ALPHA_VERTEX_CHANNEL + pass);
- vdata = mesh->vertexFloat(ALPHA_VERTEX_CHANNEL + pass);
- assert(vdata);
- for (i = 0; i < numVert; i++)
- {
- if (mesh->VertSel()[i])
- {
- vdata[i] = 0.0f;
- }
- }
- }
- // Tracks the state of the FIND check box.
- int box_checked = 0;
- if (Message == AM_UPDATE_DATA)
- {
- // The user has updated the dialog box, so update the data.
- assert(vdata);
- pblock->GetValue(DL_FIND_CHECK_BOX, t, box_checked, valid);
- if (!box_checked)
- {
- for (i = 0; i < numVert; i++)
- {
- if (SelectedVertices[i])
- {
- vdata[i] = sparam;
- }
- }
- }
- }
- if (Message == AM_BOX_CHECKED)
- {
- pblock->GetValue(DL_FIND_CHECK_BOX, t, box_checked, valid);
- }
- // The user is trying to find vertices with certain values.
- if (box_checked)
- {
- assert(vdata);
- // Find the vertices that have the user entered value.
- for (i = 0; i < numVert; i++)
- {
- if (vdata[i] == sparam)
- {
- mesh->VertSel().Set(i);
- SelectedVertices.Set(i);
- }
- else
- {
- mesh->VertSel().Clear(i);
- SelectedVertices.Clear(i);
- }
- }
-
- }
- if (Message == AM_INITIALIZE)
- {
- assert(vdata);
- SelectedVertices = mesh->VertSel();
- for (i = 0; i < numVert; i++)
- {
- if (SelectedVertices[i])
- {
- // Set the value in the dialog box to the value of the
- // first selected vertex.
- pblock->SetValue(DL_EDIT_VALUE, t, vdata[i]);
- break;
- }
- }
- }
- // Always select the vertices that have been saved by the modifier.
- // This must be done because the mesh changes each time ModfiyObject is called.
- for (i = 0; i < numVert; i++)
- {
- if (SelectedVertices[i])
- {
- mesh->VertSel().Set(i);
- }
- else
- {
- mesh->VertSel().Clear(i);
- }
- }
- // Display the vertices.
- mesh->SetDispFlag(DISP_SELVERTS | DISP_VERTTICKS);
- mesh->selLevel = MESH_VERTEX;
- object->UpdateValidity(SELECT_CHAN_NUM, object->ChannelValidity (t, SELECT_CHAN_NUM));
- // Clear messages.
- Message = AM_NOTHING;
- }
- /*===========================================================================*\
- | NotifyInputChanged is called each time the input object is changed in some way
- | We can find out how it was changed by checking partID and message
- \*===========================================================================*/
- void AlphaModifierClass::NotifyInputChanged(Interval changeInt, PartID partID, RefMessage message, ModContext *mc)
- {
- if( (partID&PART_TOPO) || (partID&PART_GEOM) || (partID&PART_SELECT) )
- {
- NotifyDependents(FOREVER, PART_OBJ, REFMSG_CHANGE);
- }
- }
- /*===========================================================================*\
- | Class Descriptor OSM
- \*===========================================================================*/
- class AlphaClassDesc : public ClassDesc2 {
- public:
- int IsPublic() { return TRUE; }
- void * Create( BOOL loading ) { return new AlphaModifierClass; }
- const TCHAR * ClassName() { return Get_String(IDS_ALPHA_MODIFIER_CLASS); }
- SClass_ID SuperClassID() { return OSM_CLASS_ID; }
- Class_ID ClassID() { return ALPHA_MODIFIER_CLASSID; }
- const TCHAR* Category() { return _T(""); }
- HINSTANCE HInstance() { return AppInstance; }
- // Hardwired name, used by MAX Script as unique identifier
- const TCHAR* InternalName() { return _T("AlphaMod"); }
- };
- static AlphaClassDesc AlphaCD;
- ClassDesc* Get_Alpha_Desc() {return &AlphaCD;}
- /*===========================================================================*\
- | Paramblock2 Descriptor
- \*===========================================================================*/
- static ParamBlockDesc2 alpha_param_blk
- (
- //rollout
- 0, _T("AlphaModifierParams"), 0, &AlphaCD, P_AUTO_CONSTRUCT + P_AUTO_UI, 0,
- IDD_ALPHA_MODIFIER, IDS_PARAMETERS, 0, 0, NULL,
- // params
-
- DL_EDIT_VALUE, _T("Custom Data Value"), TYPE_FLOAT, P_ANIMATABLE, IDS_ALPHA_MODIFIER_CLASS,
- p_default, 0.0f,
- p_range, 0.0f, 100.0f,
- p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_ALPHA_EDIT, IDC_ALPHA_SPIN, 1.0f,
- end,
- DL_FIND_CHECK_BOX, _T("1 Custom Data Value"), TYPE_BOOL, 0, IDS_ALPHA_MODIFIER_CLASS,
- p_default, FALSE,
- p_ui, TYPE_SINGLECHEKBOX, IDC_ALPHA_CHECKBOX,
- p_enabled, TRUE,
- end,
- /*
- DL_EDIT_PASS, _T("2 Custom Data Value"), TYPE_INT, P_ANIMATABLE, IDS_ALPHA_MODIFIER_CLASS,
- p_default, 1,
- p_range, 1, 4,
- p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_ALPHA_EDIT2, IDC_ALPHA_SPIN2, 1.0,
- end,
- */
- end
- );
- /*===========================================================================*\
- | Basic implementation of a dialog handler
- \*===========================================================================*/
- BOOL AlphaModDlgProc::DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- int id = LOWORD(wParam);
- int code = HIWORD(wParam);
- switch (msg)
- {
- case WM_INITDIALOG:
- AlphaModifier->Message = AM_INITIALIZE;
- break;
- case WM_DESTROY:
- break;
- case WM_COMMAND:
- switch (code)
- {
- case EN_UPDATE:
- break;
- case EN_SETFOCUS:
- break;
- case EN_KILLFOCUS:
- break;
- case EN_CHANGE:
- break;
- }
- if (id == IDC_ALPHA_EDIT)
- {
- AlphaModifier->Message = AM_UPDATE_DATA;
- }
- if (id == IDC_ALPHA_CHECKBOX)
- {
- AlphaModifier->Message = AM_BOX_CHECKED;
- }
- break;
- case WM_NOTIFY:
- if (id == IDC_ALPHA_EDIT)
- {
- AlphaModifier->Message = AM_UPDATE_DATA;
- }
- break;
- default:
- break;
- }
- return FALSE;
- }
- /*===========================================================================*\
- | Constructor
- | Ask the ClassDesc2 to make the AUTO_CONSTRUCT paramblocks and wire them in
- \*===========================================================================*/
- AlphaModifierClass::AlphaModifierClass()
- {
- AlphaCD.MakeAutoParamBlocks(this);
- assert(pblock);
- Message = 0;
- }
- /*===========================================================================*\
- | Invalidate our UI (or the recently changed parameter)
- \*===========================================================================*/
- void AlphaModifierClass::InvalidateUI()
- {
- alpha_param_blk.InvalidateUI(pblock->LastNotifyParamID());
- }
- /*===========================================================================*\
- | Open and Close dialog UIs
- | We ask the ClassDesc2 to handle Beginning and Ending EditParams for us
- \*===========================================================================*/
- void AlphaModifierClass::BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev )
- {
- AlphaCD.BeginEditParams(ip, this, flags, prev);
- alpha_param_blk.SetUserDlgProc(new AlphaModDlgProc(this));
- }
-
- void AlphaModifierClass::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
- {
- AlphaCD.EndEditParams(ip, this, flags, next);
- }
- /*===========================================================================*\
- | Standard clone
- \*===========================================================================*/
- RefTargetHandle AlphaModifierClass::Clone(RemapDir& remap)
- {
- AlphaModifierClass* newmod = new AlphaModifierClass();
- newmod->ReplaceReference(0,pblock->Clone(remap));
- return(newmod);
- }
- /*===========================================================================*\
- | Subanim & References support
- \*===========================================================================*/
- Animatable* AlphaModifierClass::SubAnim(int i)
- {
- switch (i)
- {
- case 0: return pblock;
- default: return NULL;
- }
- }
- TSTR AlphaModifierClass::SubAnimName(int i)
- {
- switch (i)
- {
- case 0: return Get_String(IDS_PARAMETERS);
- default: return _T("");
- }
- }
- RefTargetHandle AlphaModifierClass::GetReference(int i)
- {
- switch (i)
- {
- case 0: return pblock;
- default:
- assert(TRUE);
- return NULL;
- }
- }
- void AlphaModifierClass::SetReference(int i, RefTargetHandle rtarg)
- {
- switch (i)
- {
- case 0: pblock = (IParamBlock2*)rtarg; break;
- default:
- assert(TRUE);
- break;
- }
- }
- RefResult AlphaModifierClass::NotifyRefChanged
- (
- Interval changeInt,
- RefTargetHandle hTarget,
- PartID& partID,
- RefMessage message
- )
- {
- switch (message)
- {
- case REFMSG_CHANGE:
- {
- alpha_param_blk.InvalidateUI();
- }
- break;
- }
- return REF_SUCCEED;
- }
- /*===========================================================================*\
- | The validity of our parameters
- | Start at FOREVER, and intersect with the validity of each item
- \*===========================================================================*/
- Interval AlphaModifierClass::GetValidity(TimeValue t)
- {
- float f;
- Interval valid = FOREVER;
- pblock->GetValue(DL_EDIT_VALUE, t, f, valid);
- return valid;
- }
- Interval AlphaModifierClass::LocalValidity(TimeValue t)
- {
- return GetValidity(t);
- }
|