You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1810 lines
54 KiB
1810 lines
54 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, 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/>. |
|
|
|
Additional permissions under GNU GPL version 3 section 7 |
|
|
|
If you modify this Program, or any covered work, by linking or |
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
(or a modified version of those libraries), |
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
licensors of this Program grant you additional |
|
permission to convey the resulting work. Corresponding Source for a |
|
non-source form of such a combination shall include the source code for |
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
work. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
#include "HeadSpin.h" |
|
|
|
|
|
#include "max.h" |
|
#include "resource.h" |
|
#include "plComponent.h" |
|
#include "plComponentReg.h" |
|
#include "../MaxMain/plPlasmaRefMsgs.h" |
|
#include "plPickNode.h" |
|
|
|
#include "../MaxMain/plMaxNode.h" |
|
#include "../MaxExport/plExportProgressBar.h" |
|
#include "../MaxConvert/hsMaterialConverter.h" |
|
|
|
#include "hsTypes.h" |
|
#include "plTweak.h" |
|
|
|
#include "hsResMgr.h" |
|
#include "../pnMessage/plNodeRefMsg.h" |
|
#include "../pnMessage/plObjRefMsg.h" |
|
|
|
#include "../plDrawable/plDynaFootMgr.h" |
|
#include "../plDrawable/plDynaRippleMgr.h" |
|
#include "../plDrawable/plDynaRippleVSMgr.h" |
|
#include "../plDrawable/plDynaBulletMgr.h" |
|
#include "../plDrawable/plDynaPuddleMgr.h" |
|
#include "../plDrawable/plDynaTorpedoMgr.h" |
|
#include "../plDrawable/plDynaTorpedoVSMgr.h" |
|
#include "../plDrawable/plDynaWakeMgr.h" |
|
#include "../plDrawable/plCutter.h" |
|
#include "../plModifier/plDecalEnableMod.h" |
|
#include "../plDrawable/plPrintShape.h" |
|
#include "../plDrawable/plActivePrintShape.h" |
|
|
|
#include "../plSurface/hsGMaterial.h" |
|
#include "../plSurface/plLayer.h" |
|
|
|
#include "plWaterComponent.h" |
|
#include "../plDrawable/plWaveSetBase.h" |
|
|
|
#include "plParticleComponents.h" |
|
|
|
void DummyCodeIncludeFuncFootPrint() |
|
{ |
|
} |
|
|
|
|
|
const Class_ID FOOTPRINT_COMP_CID(0x5d553f57, 0x42344c5e); |
|
const Class_ID RIPPLE_COMP_CID(0x750e1b2a, 0x4ad10f15); |
|
const Class_ID PUDDLE_COMP_CID(0x2f800331, 0x640f4914); |
|
const Class_ID WAKE_COMP_CID(0x714b6b6b, 0xa937ff4); |
|
const Class_ID BULLET_COMP_CID(0x208c05d7, 0x41540df2); |
|
const Class_ID TORPEDO_COMP_CID(0x72b85c86, 0xe2b0b40); |
|
|
|
const Class_ID DIRTY_COMP_CID(0x500f1fd3, 0x508c4486); |
|
|
|
|
|
|
|
class plFootPrintComponent : public plComponent |
|
{ |
|
protected: |
|
plDynaDecalMgr* fDecalMgr; |
|
bool fValid; |
|
|
|
bool fNotifiesSetup; |
|
|
|
hsBool ISetupNotifies(plMaxNode* node, plErrorMsg* pErrMsg); |
|
hsBool ISetupDecalMgr(plMaxNode* node, plErrorMsg* pErrMsg, plDynaDecalMgr* decalMgr); |
|
hsBool ICreateDecalMaterials(plMaxNode* node, plErrorMsg* pErrMsg); |
|
hsBool ISetupColorDecalMaterials(plMaxNode* node, plErrorMsg* pErrMsg); |
|
|
|
hsBool ISetupParticles(plMaxNode* node, plErrorMsg* pErrMsg); |
|
|
|
static plParticleComponent* IGetParticleComp(INode* node); |
|
|
|
virtual void IFakeParams(); |
|
public: |
|
enum |
|
{ |
|
kWidth, |
|
kLength, |
|
kFadeIn, |
|
kFadeOut, |
|
kLifeSpan, |
|
kLayer, |
|
kBlend, |
|
kDirtyTime, |
|
kNotifies, |
|
kIntensity, |
|
kParticles, |
|
kPartyTime |
|
}; |
|
enum |
|
{ |
|
kAlpha, |
|
kMADD, |
|
kAdd, |
|
kMult |
|
}; |
|
|
|
plFootPrintComponent(); |
|
virtual ~plFootPrintComponent(); |
|
void DeleteThis() { delete this; } |
|
|
|
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading |
|
// of properties on the MaxNode, as it's still indeterminant. |
|
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool DeInit(plMaxNode *node, plErrorMsg *pErrMsg); |
|
|
|
|
|
static plDynaDecalMgr* GetDecalMgr(INode* node); |
|
}; |
|
|
|
|
|
CLASS_DESC(plFootPrintComponent, gFootPrintCompDesc, "Foot Print", "FootPrint", COMP_TYPE_FOOTPRINT, FOOTPRINT_COMP_CID) |
|
|
|
|
|
class plWetProc : public ParamMap2UserDlgProc |
|
{ |
|
public: |
|
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
|
{ |
|
switch (msg) |
|
{ |
|
case WM_INITDIALOG: |
|
{ |
|
} |
|
return true; |
|
|
|
case WM_COMMAND: |
|
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ADD_NOTIFY) |
|
{ |
|
std::vector<Class_ID> cids; |
|
cids.push_back(FOOTPRINT_COMP_CID); |
|
cids.push_back(RIPPLE_COMP_CID); |
|
cids.push_back(PUDDLE_COMP_CID); |
|
cids.push_back(WAKE_COMP_CID); |
|
IParamBlock2 *pb = map->GetParamBlock(); |
|
plPick::Node(pb, plFootPrintComponent::kNotifies, &cids, false, false); |
|
|
|
map->Invalidate(plFootPrintComponent::kNotifies); |
|
return TRUE; |
|
} |
|
else |
|
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ADD_PARTICLE) |
|
{ |
|
std::vector<Class_ID> cids; |
|
cids.push_back(PARTICLE_SYSTEM_COMPONENT_CLASS_ID); |
|
IParamBlock2 *pb = map->GetParamBlock(); |
|
plPick::Node(pb, plFootPrintComponent::kParticles, &cids, false, false); |
|
|
|
map->Invalidate(plFootPrintComponent::kParticles); |
|
return TRUE; |
|
} |
|
break; |
|
} |
|
|
|
return false; |
|
} |
|
void DeleteThis() {} |
|
}; |
|
static plWetProc gWetProc; |
|
|
|
///////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
ParamBlockDesc2 gFootPrintBk |
|
( |
|
plComponent::kBlkComp, _T("FootPrint"), 0, &gFootPrintCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, |
|
|
|
IDD_COMP_FP_FOOTPRINT, IDS_COMP_FOOTPRINT, 0, 0, &gWetProc, |
|
|
|
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 25.0, 400.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_WIDTH, IDC_COMP_FP_WIDTH_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 25.0, 400.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0, |
|
// p_default, 10.0, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0, |
|
p_default, 30.0, |
|
p_range, 0.0, 300.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0, |
|
// p_default, 0.1, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0, |
|
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP, |
|
end, |
|
|
|
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT, |
|
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult, |
|
p_default, plFootPrintComponent::kAlpha, |
|
end, |
|
|
|
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0, |
|
p_default, 10.0, |
|
p_range, 0.0, 300.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS, |
|
end, |
|
|
|
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 0.0, 100.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2, |
|
end, |
|
|
|
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.25, |
|
p_range, 0.1, 5.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
end |
|
); |
|
|
|
hsBool plFootPrintComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
// If we don't have a valid layer, we're screwed. Throw up a warning |
|
// and shutdown. |
|
if( !fCompPB->GetTexmap(kLayer) ) |
|
{ |
|
pErrMsg->Set(true, GetINode()->GetName(), "No layer setup. Ignoring Footprint generator").CheckAndAsk(); |
|
pErrMsg->Set(false); |
|
fValid = false; |
|
return true; |
|
} |
|
|
|
fDecalMgr = nil; |
|
|
|
fValid = true; |
|
fNotifiesSetup = false; |
|
|
|
return true; |
|
} |
|
|
|
hsBool plFootPrintComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( !fValid ) |
|
return true; |
|
|
|
// If we haven't already, create our DynaDecalMgr and stash it away. |
|
if( !fDecalMgr ) |
|
{ |
|
ISetupDecalMgr(node, pErrMsg, TRACKED_NEW plDynaFootMgr); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
hsBool plFootPrintComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( !fValid ) |
|
return true; |
|
|
|
if( !fNotifiesSetup ) |
|
ISetupNotifies(node, pErrMsg); |
|
|
|
// Add this node's object to our DynaDecalMgr. |
|
hsgResMgr::ResMgr()->AddViaNotify(node->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefTarget), plRefFlags::kActiveRef); |
|
|
|
return true; |
|
} |
|
|
|
hsBool plFootPrintComponent::DeInit(plMaxNode *node, plErrorMsg *pErrMsg) |
|
{ |
|
fDecalMgr = nil; |
|
return true; |
|
} |
|
|
|
plFootPrintComponent::plFootPrintComponent() |
|
: fDecalMgr(nil) |
|
{ |
|
fClassDesc = &gFootPrintCompDesc; |
|
fClassDesc->MakeAutoParamBlocks(this); |
|
} |
|
|
|
plFootPrintComponent::~plFootPrintComponent() |
|
{ |
|
} |
|
|
|
void plFootPrintComponent::IFakeParams() |
|
{ |
|
fCompPB->SetValue(kFadeIn, TimeValue(0), 0.1f); |
|
fCompPB->SetValue(kFadeOut, TimeValue(0), fCompPB->GetFloat(kLifeSpan) * 0.25f); |
|
} |
|
|
|
hsBool plFootPrintComponent::ISetupDecalMgr(plMaxNode* node, plErrorMsg* pErrMsg, plDynaDecalMgr* decalMgr) |
|
{ |
|
IFakeParams(); |
|
|
|
fDecalMgr = decalMgr; |
|
plKey mgrKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), fDecalMgr, node->GetLocation()); |
|
|
|
float width = fCompPB->GetFloat(kWidth) * 1.e-2f; |
|
float length = fCompPB->GetFloat(kLength) * 1.e-2f; |
|
float wetTime = fCompPB->GetFloat(kDirtyTime); |
|
float fadeIn = fCompPB->GetFloat(kFadeIn); |
|
float fadeOut = fCompPB->GetFloat(kFadeOut); |
|
float lifeSpan = fCompPB->GetFloat(kLifeSpan); |
|
float intensity = fCompPB->GetFloat(kIntensity) * 1.e-2f; |
|
float partyTime = fCompPB->GetFloat(kPartyTime); |
|
|
|
const hsScalar kHeightHack = 1.f; |
|
fDecalMgr->SetScale(hsVector3(width, length, kHeightHack)); |
|
|
|
const float kMinFadeOut = 1.e-2f; |
|
if( fadeOut > lifeSpan - kMinFadeOut) |
|
fadeOut = lifeSpan - kMinFadeOut; |
|
if( fadeIn > lifeSpan - fadeOut ) |
|
fadeIn = lifeSpan - fadeOut; |
|
|
|
fDecalMgr->SetWetLength(wetTime); |
|
fDecalMgr->SetRampEnd(fadeIn); |
|
fDecalMgr->SetDecayStart(lifeSpan - fadeOut); |
|
fDecalMgr->SetLifeSpan(lifeSpan); |
|
fDecalMgr->SetIntensity(intensity); |
|
fDecalMgr->SetPartyTime(partyTime); |
|
|
|
if( !ICreateDecalMaterials(node, pErrMsg) ) |
|
{ |
|
delete fDecalMgr; |
|
fDecalMgr = nil; |
|
return fValid = false; |
|
} |
|
|
|
hsgResMgr::ResMgr()->AddViaNotify(mgrKey, TRACKED_NEW plNodeRefMsg(node->GetRoomKey(), plRefMsg::kOnCreate, -1, plNodeRefMsg::kGeneric), plRefFlags::kActiveRef); |
|
|
|
ISetupParticles(node, pErrMsg); |
|
|
|
return true; |
|
} |
|
|
|
hsBool plFootPrintComponent::ISetupNotifies(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
int num = fCompPB->Count(kNotifies); |
|
int i; |
|
for( i = 0; i < num; i++ ) |
|
{ |
|
plDynaDecalMgr* slave = GetDecalMgr(fCompPB->GetINode(kNotifies, TimeValue(0), i)); |
|
if( slave ) |
|
{ |
|
slave->SetWaitOnEnable(true); |
|
fDecalMgr->AddNotify(slave->GetKey()); |
|
} |
|
} |
|
fNotifiesSetup = true; |
|
|
|
return true; |
|
} |
|
|
|
hsBool plFootPrintComponent::ISetupParticles(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
int num = fCompPB->Count(kParticles); |
|
if( !num ) |
|
return true; |
|
|
|
int i; |
|
for( i = 0; i < num; i++ ) |
|
{ |
|
plParticleComponent* partyComp = IGetParticleComp(fCompPB->GetINode(kParticles, TimeValue(0), i)); |
|
if( partyComp && partyComp->NumTargets() ) |
|
{ |
|
plMaxNodeBase* partyNode = nil; |
|
const int numTarg = partyComp->NumTargets(); |
|
int j; |
|
for( j = 0; j < numTarg; j++ ) |
|
{ |
|
partyNode = partyComp->GetTarget(j); |
|
if( partyNode ) |
|
break; |
|
} |
|
if( partyNode ) |
|
{ |
|
plSceneObject* obj = partyNode->GetSceneObject(); |
|
if( obj ) |
|
{ |
|
hsgResMgr::ResMgr()->AddViaNotify(obj->GetKey(), |
|
new plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefPartyObject), plRefFlags::kPassiveRef); |
|
} |
|
} |
|
plConst(int) kNumEmitters(3); |
|
partyComp->SetEmitterReserve(kNumEmitters); |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
hsBool plFootPrintComponent::ICreateDecalMaterials(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( fCompPB->GetInt(kBlend) != kAlpha ) |
|
return ISetupColorDecalMaterials(node, pErrMsg); |
|
|
|
hsGMaterial* matRTShade = hsMaterialConverter::Instance().NonAlphaHackPrint(node, fCompPB->GetTexmap(kLayer), hsGMatState::kBlendAlpha); |
|
|
|
if( !matRTShade ) |
|
return fValid = false; |
|
|
|
hsgResMgr::ResMgr()->AddViaNotify(matRTShade->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefMatRTShade), plRefFlags::kActiveRef); |
|
|
|
hsGMaterial* matPreShade = hsMaterialConverter::Instance().AlphaHackPrint(node, fCompPB->GetTexmap(kLayer), hsGMatState::kBlendAlpha); |
|
|
|
hsgResMgr::ResMgr()->AddViaNotify(matPreShade->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefMatPreShade), plRefFlags::kActiveRef); |
|
|
|
return true; |
|
} |
|
|
|
hsBool plFootPrintComponent::ISetupColorDecalMaterials(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
UInt32 blendFlags = 0; |
|
switch( fCompPB->GetInt(kBlend) ) |
|
{ |
|
case kMADD: |
|
blendFlags = hsGMatState::kBlendMADD; |
|
break; |
|
case kAdd: |
|
blendFlags = hsGMatState::kBlendAdd; |
|
break; |
|
case kMult: |
|
blendFlags = hsGMatState::kBlendMult; |
|
break; |
|
default: |
|
hsAssert(false, "Unknown blend mode"); |
|
blendFlags = hsGMatState::kBlendMADD; // cuz it's my fave. |
|
break; |
|
} |
|
hsGMaterial* matRTShade = hsMaterialConverter::Instance().NonAlphaHackPrint(node, fCompPB->GetTexmap(kLayer), blendFlags); |
|
|
|
if( blendFlags & hsGMatState::kBlendMult ) |
|
{ |
|
plLayer* layer = plLayer::ConvertNoRef(matRTShade->GetLayer(0)->BottomOfStack()); |
|
if( !layer ) |
|
return fValid = false; |
|
|
|
layer->SetBlendFlags(layer->GetBlendFlags() | hsGMatState::kBlendInvertFinalColor); |
|
} |
|
|
|
hsgResMgr::ResMgr()->AddViaNotify(matRTShade->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefMatRTShade), plRefFlags::kActiveRef); |
|
|
|
return true; |
|
} |
|
|
|
plParticleComponent* plFootPrintComponent::IGetParticleComp(INode* node) |
|
{ |
|
if( !node ) |
|
return nil; |
|
|
|
plComponentBase *comp = ((plMaxNodeBase*)node)->ConvertToComponent(); |
|
if( comp == nil ) |
|
return nil; |
|
|
|
if( comp->ClassID() == PARTICLE_SYSTEM_COMPONENT_CLASS_ID ) |
|
{ |
|
plParticleComponent* party = (plParticleComponent*)comp; |
|
return party; |
|
} |
|
|
|
return nil; |
|
} |
|
|
|
plDynaDecalMgr* plFootPrintComponent::GetDecalMgr(INode* node) |
|
{ |
|
if( !node ) |
|
return nil; |
|
|
|
plComponentBase *comp = ((plMaxNodeBase*)node)->ConvertToComponent(); |
|
if( comp == nil ) |
|
return nil; |
|
|
|
if( (comp->ClassID() == FOOTPRINT_COMP_CID) |
|
|| (comp->ClassID() == RIPPLE_COMP_CID) |
|
|| (comp->ClassID() == PUDDLE_COMP_CID) |
|
|| (comp->ClassID() == WAKE_COMP_CID) |
|
) |
|
{ |
|
plFootPrintComponent* foot = (plFootPrintComponent*)comp; |
|
return foot->fDecalMgr; |
|
} |
|
|
|
return nil; |
|
} |
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
class plRippleComponent : public plFootPrintComponent |
|
{ |
|
protected: |
|
virtual void IFakeParams(); |
|
public: |
|
|
|
plRippleComponent(); |
|
virtual ~plRippleComponent(); |
|
void DeleteThis() { delete this; } |
|
|
|
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading |
|
// of properties on the MaxNode, as it's still indeterminant. |
|
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
}; |
|
|
|
|
|
CLASS_DESC(plRippleComponent, gRippleCompDesc, "Ripple", "Ripple", COMP_TYPE_FOOTPRINT, RIPPLE_COMP_CID) |
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
ParamBlockDesc2 gRippleBk |
|
( |
|
plComponent::kBlkComp, _T("Ripple"), 0, &gRippleCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, |
|
|
|
IDD_COMP_FP_RIPPLE, IDS_COMP_RIPPLE, 0, 0, &gWetProc, |
|
|
|
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 25.0, 1000.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_WIDTH, IDC_COMP_FP_WIDTH_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0, |
|
// p_default, 1.0, |
|
// p_range, 0.25, 10.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0, |
|
// p_default, 3.5, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0, |
|
// p_default, 5.0, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0, |
|
// p_default, 0.25, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0, |
|
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP, |
|
end, |
|
|
|
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT, |
|
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult, |
|
p_default, plFootPrintComponent::kAlpha, |
|
end, |
|
|
|
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0, |
|
p_default, 10.0, |
|
p_range, 0.0, 300.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS, |
|
end, |
|
|
|
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 0.0, 100.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2, |
|
end, |
|
|
|
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.25, |
|
p_range, 0.1, 5.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
end |
|
); |
|
|
|
void plRippleComponent::IFakeParams() |
|
{ |
|
fCompPB->SetValue(kLength, TimeValue(0), fCompPB->GetFloat(kWidth)); |
|
fCompPB->SetValue(kFadeIn, TimeValue(0), 0.25f); |
|
fCompPB->SetValue(kLifeSpan, TimeValue(0), fCompPB->GetFloat(kWidth) * 1.e-2f * 0.5f); |
|
fCompPB->SetValue(kFadeOut, TimeValue(0), fCompPB->GetFloat(kLifeSpan) * 0.80f); |
|
} |
|
|
|
hsBool plRippleComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
return plFootPrintComponent::SetupProperties(node, pErrMsg); |
|
} |
|
|
|
hsBool plRippleComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( !fValid ) |
|
return true; |
|
|
|
// If we haven't already, create our DynaDecalMgr and stash it away. |
|
if( !fDecalMgr ) |
|
{ |
|
plDynaRippleMgr* ripple = nil; |
|
if( node->GetVS() || node->UserPropExists("XXXWaterColor") ) |
|
{ |
|
ripple = TRACKED_NEW plDynaRippleVSMgr; |
|
} |
|
else |
|
{ |
|
ripple = TRACKED_NEW plDynaRippleMgr; |
|
} |
|
ISetupDecalMgr(node, pErrMsg, ripple); |
|
if( fValid ) |
|
{ |
|
ripple->SetUVWAnim(hsVector3(3.f, 3.f, 3.f), hsVector3(1.f, 1.f, 1.f)); |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
hsBool plRippleComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( !fValid ) |
|
return true; |
|
|
|
if( !fNotifiesSetup ) |
|
{ |
|
plWaveSetBase* waveSet = plWaterComponent::GetWaveSetFromNode(node); |
|
if( waveSet ) |
|
{ |
|
plGenRefMsg* refMsg = TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaRippleVSMgr::kRefWaveSetBase); |
|
hsgResMgr::ResMgr()->AddViaNotify(waveSet->GetKey(), refMsg, plRefFlags::kPassiveRef); |
|
} |
|
|
|
ISetupNotifies(node, pErrMsg); |
|
} |
|
|
|
// Add this node's object to our DynaDecalMgr. |
|
hsgResMgr::ResMgr()->AddViaNotify(node->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefTarget), plRefFlags::kActiveRef); |
|
|
|
return true; |
|
} |
|
|
|
plRippleComponent::plRippleComponent() |
|
{ |
|
fClassDesc = &gRippleCompDesc; |
|
fClassDesc->MakeAutoParamBlocks(this); |
|
} |
|
|
|
plRippleComponent::~plRippleComponent() |
|
{ |
|
} |
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
class plPuddleComponent : public plRippleComponent |
|
{ |
|
protected: |
|
public: |
|
|
|
plPuddleComponent(); |
|
virtual ~plPuddleComponent(); |
|
void DeleteThis() { delete this; } |
|
|
|
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading |
|
// of properties on the MaxNode, as it's still indeterminant. |
|
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
}; |
|
|
|
|
|
CLASS_DESC(plPuddleComponent, gPuddleCompDesc, "Puddle", "Puddle", COMP_TYPE_FOOTPRINT, PUDDLE_COMP_CID) |
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
ParamBlockDesc2 gPuddleBk |
|
( |
|
plComponent::kBlkComp, _T("Puddle"), 0, &gPuddleCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, |
|
|
|
IDD_COMP_FP_PUDDLE, IDS_COMP_PUDDLE, 0, 0, &gWetProc, |
|
|
|
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 25.0, 1000.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_WIDTH, IDC_COMP_FP_WIDTH_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0, |
|
// p_default, 1.0, |
|
// p_range, 0.25, 10.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0, |
|
// p_default, 3.5, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0, |
|
// p_default, 5.0, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0, |
|
// p_default, 0.25, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0, |
|
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP, |
|
end, |
|
|
|
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT, |
|
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult, |
|
p_default, plFootPrintComponent::kAlpha, |
|
end, |
|
|
|
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0, |
|
p_default, 10.0, |
|
p_range, 0.0, 300.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS, |
|
end, |
|
|
|
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 0.0, 100.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2, |
|
end, |
|
|
|
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.25, |
|
p_range, 0.1, 5.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
end |
|
); |
|
|
|
hsBool plPuddleComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
return plRippleComponent::SetupProperties(node, pErrMsg); |
|
} |
|
|
|
hsBool plPuddleComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( !fValid ) |
|
return true; |
|
|
|
// If we haven't already, create our DynaDecalMgr and stash it away. |
|
if( !fDecalMgr ) |
|
{ |
|
plDynaRippleMgr* puddle = TRACKED_NEW plDynaPuddleMgr; |
|
|
|
ISetupDecalMgr(node, pErrMsg, puddle); |
|
if( fValid ) |
|
{ |
|
puddle->SetUVWAnim(hsVector3(5.f, 5.f, 5.f), hsVector3(1.f, 1.f, 1.f)); |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
hsBool plPuddleComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( !fValid ) |
|
return true; |
|
|
|
if( !fNotifiesSetup ) |
|
ISetupNotifies(node, pErrMsg); |
|
|
|
// Add this node's object to our DynaDecalMgr. |
|
hsgResMgr::ResMgr()->AddViaNotify(node->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefTarget), plRefFlags::kActiveRef); |
|
|
|
return true; |
|
} |
|
|
|
plPuddleComponent::plPuddleComponent() |
|
{ |
|
fClassDesc = &gPuddleCompDesc; |
|
fClassDesc->MakeAutoParamBlocks(this); |
|
} |
|
|
|
plPuddleComponent::~plPuddleComponent() |
|
{ |
|
} |
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
class plBulletComponent : public plFootPrintComponent |
|
{ |
|
protected: |
|
virtual void IFakeParams(); |
|
public: |
|
|
|
plBulletComponent(); |
|
virtual ~plBulletComponent(); |
|
void DeleteThis() { delete this; } |
|
|
|
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading |
|
// of properties on the MaxNode, as it's still indeterminant. |
|
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
}; |
|
|
|
|
|
CLASS_DESC(plBulletComponent, gBulletCompDesc, "Bullet", "Bullet", COMP_TYPE_FOOTPRINT, BULLET_COMP_CID) |
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
ParamBlockDesc2 gBulletBk |
|
( |
|
plComponent::kBlkComp, _T("Bullet"), 0, &gBulletCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, |
|
|
|
IDD_COMP_FP_BULLET, IDS_COMP_FP_BULLET, 0, 0, &gWetProc, |
|
|
|
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 25.0, 400.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_SCALE, IDC_COMP_FP_SCALE_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0, |
|
// p_default, 100.0, |
|
// p_range, 25.0, 400.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0, |
|
// p_default, 10.0, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0, |
|
p_default, 15.0, |
|
p_range, 0.0, 300.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0, |
|
// p_default, 0.1, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0, |
|
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP, |
|
end, |
|
|
|
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT, |
|
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult, |
|
p_default, plFootPrintComponent::kAlpha, |
|
end, |
|
|
|
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0, |
|
// p_default, 10.0, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0, |
|
// p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS, |
|
end, |
|
|
|
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 0.0, 100.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2, |
|
end, |
|
|
|
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.25, |
|
p_range, 0.1, 5.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
end |
|
); |
|
|
|
void plBulletComponent::IFakeParams() |
|
{ |
|
fCompPB->SetValue(kLength, TimeValue(0), fCompPB->GetFloat(kWidth)); |
|
plFootPrintComponent::IFakeParams(); |
|
} |
|
|
|
hsBool plBulletComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
return plFootPrintComponent::SetupProperties(node, pErrMsg); |
|
} |
|
|
|
hsBool plBulletComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( !fValid ) |
|
return true; |
|
|
|
// If we haven't already, create our DynaDecalMgr and stash it away. |
|
if( !fDecalMgr ) |
|
{ |
|
plDynaBulletMgr* bullet = TRACKED_NEW plDynaBulletMgr; |
|
|
|
ISetupDecalMgr(node, pErrMsg, bullet); |
|
} |
|
return true; |
|
} |
|
|
|
hsBool plBulletComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( !fValid ) |
|
return true; |
|
|
|
if( !fNotifiesSetup ) |
|
ISetupNotifies(node, pErrMsg); |
|
|
|
// Add this node's object to our DynaDecalMgr. |
|
hsgResMgr::ResMgr()->AddViaNotify(node->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefTarget), plRefFlags::kActiveRef); |
|
|
|
return true; |
|
} |
|
|
|
plBulletComponent::plBulletComponent() |
|
{ |
|
fClassDesc = &gBulletCompDesc; |
|
fClassDesc->MakeAutoParamBlocks(this); |
|
} |
|
|
|
plBulletComponent::~plBulletComponent() |
|
{ |
|
} |
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
class plTorpedoComponent : public plRippleComponent |
|
{ |
|
protected: |
|
virtual void IFakeParams(); |
|
public: |
|
|
|
plTorpedoComponent(); |
|
virtual ~plTorpedoComponent(); |
|
void DeleteThis() { delete this; } |
|
|
|
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading |
|
// of properties on the MaxNode, as it's still indeterminant. |
|
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
}; |
|
|
|
|
|
CLASS_DESC(plTorpedoComponent, gTorpedoCompDesc, "Water Bullet", "WetBullet", COMP_TYPE_FOOTPRINT, TORPEDO_COMP_CID) |
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
ParamBlockDesc2 gTorpedoBk |
|
( |
|
plComponent::kBlkComp, _T("Torpedo"), 0, &gTorpedoCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, |
|
|
|
IDD_COMP_FP_TORPEDO, IDS_COMP_FP_TORPEDO, 0, 0, &gWetProc, |
|
|
|
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 25.0, 1000.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_WIDTH, IDC_COMP_FP_WIDTH_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0, |
|
// p_default, 1.0, |
|
// p_range, 0.25, 10.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0, |
|
// p_default, 3.5, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0, |
|
p_default, 5.0, |
|
p_range, 0.0, 10.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0, |
|
// p_default, 0.25, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0, |
|
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP, |
|
end, |
|
|
|
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT, |
|
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult, |
|
p_default, plFootPrintComponent::kAlpha, |
|
end, |
|
|
|
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0, |
|
p_default, 10.0, |
|
p_range, 0.0, 300.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS, |
|
end, |
|
|
|
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 0.0, 100.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2, |
|
end, |
|
|
|
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.25, |
|
p_range, 0.1, 5.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
end |
|
); |
|
|
|
void plTorpedoComponent::IFakeParams() |
|
{ |
|
fCompPB->SetValue(kLength, TimeValue(0), fCompPB->GetFloat(kWidth)); |
|
fCompPB->SetValue(kFadeIn, TimeValue(0), 0.25f); |
|
fCompPB->SetValue(kFadeOut, TimeValue(0), fCompPB->GetFloat(kLifeSpan) * 0.80f); |
|
} |
|
|
|
hsBool plTorpedoComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
return plRippleComponent::SetupProperties(node, pErrMsg); |
|
} |
|
|
|
hsBool plTorpedoComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( !fValid ) |
|
return true; |
|
|
|
// If we haven't already, create our DynaDecalMgr and stash it away. |
|
if( !fDecalMgr ) |
|
{ |
|
plDynaRippleMgr* torpedo; |
|
if( node->GetVS() ) |
|
torpedo = TRACKED_NEW plDynaTorpedoVSMgr; |
|
else |
|
torpedo = TRACKED_NEW plDynaTorpedoMgr; |
|
|
|
ISetupDecalMgr(node, pErrMsg, torpedo); |
|
if( fValid ) |
|
{ |
|
torpedo->SetUVWAnim(hsVector3(5.f, 5.f, 5.f), hsVector3(1.f, 1.f, 1.f)); |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
hsBool plTorpedoComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
return plRippleComponent::Convert(node, pErrMsg); |
|
} |
|
|
|
plTorpedoComponent::plTorpedoComponent() |
|
{ |
|
fClassDesc = &gTorpedoCompDesc; |
|
fClassDesc->MakeAutoParamBlocks(this); |
|
} |
|
|
|
plTorpedoComponent::~plTorpedoComponent() |
|
{ |
|
} |
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
class plWakeComponent : public plFootPrintComponent |
|
{ |
|
protected: |
|
virtual void IFakeParams(); |
|
public: |
|
|
|
plWakeComponent(); |
|
virtual ~plWakeComponent(); |
|
void DeleteThis() { delete this; } |
|
|
|
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading |
|
// of properties on the MaxNode, as it's still indeterminant. |
|
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
}; |
|
|
|
|
|
CLASS_DESC(plWakeComponent, gWakeCompDesc, "Wake", "Wake", COMP_TYPE_FOOTPRINT, WAKE_COMP_CID) |
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
ParamBlockDesc2 gWakeBk |
|
( |
|
plComponent::kBlkComp, _T("Wake"), 0, &gWakeCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, |
|
|
|
IDD_COMP_FP_WAKE, IDS_COMP_FP_WAKE, 0, 0, &gWetProc, |
|
|
|
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 25.0, 1000.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_WIDTH, IDC_COMP_FP_WIDTH_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 25.0, 1000.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0, |
|
// p_default, 3.5, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0, |
|
// p_default, 5.0, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0, |
|
// p_default, 0.25, |
|
// p_range, 0.0, 300.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0, |
|
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP, |
|
end, |
|
|
|
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT, |
|
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult, |
|
p_default, plFootPrintComponent::kAlpha, |
|
end, |
|
|
|
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0, |
|
p_default, 10.0, |
|
p_range, 0.0, 300.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS, |
|
end, |
|
|
|
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0, |
|
p_default, 100.0, |
|
p_range, 0.0, 100.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0, |
|
end, |
|
|
|
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0, |
|
// p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2, |
|
end, |
|
|
|
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0, |
|
// p_default, 0.25, |
|
// p_range, 0.1, 5.0, |
|
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
// IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
end |
|
); |
|
|
|
void plWakeComponent::IFakeParams() |
|
{ |
|
fCompPB->SetValue(kFadeIn, TimeValue(0), 0.25f); |
|
fCompPB->SetValue(kLifeSpan, TimeValue(0), fCompPB->GetFloat(kWidth) * 1.e-2f * 0.5f); |
|
fCompPB->SetValue(kFadeOut, TimeValue(0), fCompPB->GetFloat(kLifeSpan) * 0.80f); |
|
} |
|
|
|
hsBool plWakeComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
return plFootPrintComponent::SetupProperties(node, pErrMsg); |
|
} |
|
|
|
hsBool plWakeComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( !fValid ) |
|
return true; |
|
|
|
// If we haven't already, create our DynaDecalMgr and stash it away. |
|
if( !fDecalMgr ) |
|
{ |
|
plDynaWakeMgr* wake = TRACKED_NEW plDynaWakeMgr; |
|
ISetupDecalMgr(node, pErrMsg, wake); |
|
if( fValid ) |
|
{ |
|
wake->SetUVWAnim(hsVector3(5.f, 5.f, 5.f), hsVector3(1.f, 1.f, 1.f)); |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
hsBool plWakeComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
if( !fValid ) |
|
return true; |
|
|
|
if( !fNotifiesSetup ) |
|
ISetupNotifies(node, pErrMsg); |
|
|
|
// Add this node's object to our DynaDecalMgr. |
|
hsgResMgr::ResMgr()->AddViaNotify(node->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefTarget), plRefFlags::kActiveRef); |
|
|
|
return true; |
|
} |
|
|
|
plWakeComponent::plWakeComponent() |
|
{ |
|
fClassDesc = &gWakeCompDesc; |
|
fClassDesc->MakeAutoParamBlocks(this); |
|
} |
|
|
|
plWakeComponent::~plWakeComponent() |
|
{ |
|
} |
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
class plDirtyComponent : public plComponent |
|
{ |
|
public: |
|
enum |
|
{ |
|
kDecals, |
|
kDirtyTime |
|
}; |
|
protected: |
|
public: |
|
|
|
plDirtyComponent(); |
|
virtual ~plDirtyComponent(); |
|
void DeleteThis() { delete this; } |
|
|
|
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading |
|
// of properties on the MaxNode, as it's still indeterminant. |
|
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
}; |
|
|
|
|
|
CLASS_DESC(plDirtyComponent, gDirtyCompDesc, "Dirty/Wet Region", "Dirty/Wet", COMP_TYPE_FOOTPRINT, DIRTY_COMP_CID) |
|
|
|
|
|
class plDirtyProc : public ParamMap2UserDlgProc |
|
{ |
|
public: |
|
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
|
{ |
|
switch (msg) |
|
{ |
|
case WM_INITDIALOG: |
|
{ |
|
} |
|
return true; |
|
|
|
case WM_COMMAND: |
|
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ADD_DECAL) |
|
{ |
|
std::vector<Class_ID> cids; |
|
cids.push_back(FOOTPRINT_COMP_CID); |
|
cids.push_back(RIPPLE_COMP_CID); |
|
cids.push_back(PUDDLE_COMP_CID); |
|
cids.push_back(WAKE_COMP_CID); |
|
IParamBlock2 *pb = map->GetParamBlock(); |
|
plPick::Node(pb, plDirtyComponent::kDecals, &cids, false, false); |
|
|
|
map->Invalidate(plDirtyComponent::kDecals); |
|
return TRUE; |
|
} |
|
break; |
|
} |
|
|
|
return false; |
|
} |
|
void DeleteThis() {} |
|
}; |
|
static plDirtyProc gDirtyProc; |
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
ParamBlockDesc2 gDirtyBk |
|
( |
|
plComponent::kBlkComp, _T("Dirty"), 0, &gDirtyCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, |
|
|
|
IDD_COMP_FP_DIRTY, IDS_COMP_FP_DIRTY, 0, 0, &gDirtyProc, |
|
|
|
plDirtyComponent::kDecals, _T("Decals"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS, |
|
end, |
|
|
|
plDirtyComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0, |
|
p_default, 10.0, |
|
p_range, 0.0, 300.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1, |
|
end, |
|
|
|
end |
|
); |
|
|
|
hsBool plDirtyComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
return true; |
|
} |
|
|
|
hsBool plDirtyComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
return true; |
|
} |
|
|
|
hsBool plDirtyComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
// Check that this node has a physical interface, or all is for nought. |
|
// Should throw up a warning if it doesn't have one, seems an easy thing |
|
// to miss. |
|
if( !node->IsPhysical() ) |
|
{ |
|
pErrMsg->Set(true, node->GetName(), "Has no physical component to notify %s Dirty/Wet component", GetINode()->GetName()).CheckAndAsk(); |
|
pErrMsg->Set(false); |
|
return true; |
|
} |
|
|
|
|
|
plDecalEnableMod* enable = TRACKED_NEW plDecalEnableMod; |
|
plKey modKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), enable, node->GetLocation()); |
|
|
|
int numDecals = fCompPB->Count(kDecals); |
|
int i; |
|
for( i = 0; i < numDecals; i++ ) |
|
{ |
|
INode* decalNode = fCompPB->GetINode(kDecals, TimeValue(0), i); |
|
|
|
plDynaDecalMgr* decal = plFootPrintComponent::GetDecalMgr(decalNode); |
|
|
|
if( decal ) |
|
{ |
|
decal->SetWaitOnEnable(true); |
|
enable->AddDecalKey(decal->GetKey()); |
|
} |
|
} |
|
enable->SetWetLength(fCompPB->GetFloat(kDirtyTime)); |
|
hsgResMgr::ResMgr()->AddViaNotify(modKey, TRACKED_NEW plObjRefMsg(node->GetKey(), plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef); |
|
|
|
return true; |
|
} |
|
|
|
plDirtyComponent::plDirtyComponent() |
|
{ |
|
fClassDesc = &gDirtyCompDesc; |
|
fClassDesc->MakeAutoParamBlocks(this); |
|
} |
|
|
|
plDirtyComponent::~plDirtyComponent() |
|
{ |
|
} |
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
const Class_ID PRINTSHAPE_COMP_CID(0x208226a1, 0x2a6e67ba); |
|
|
|
class plPrintShapeComponent : public plComponent |
|
{ |
|
public: |
|
enum |
|
{ |
|
kWidth, |
|
kLength, |
|
kHeight |
|
}; |
|
protected: |
|
public: |
|
|
|
plPrintShapeComponent(); |
|
virtual ~plPrintShapeComponent(); |
|
void DeleteThis() { delete this; } |
|
|
|
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading |
|
// of properties on the MaxNode, as it's still indeterminant. |
|
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
}; |
|
|
|
|
|
CLASS_DESC(plPrintShapeComponent, gPrintShapeCompDesc, "Print Shape", "PrintShape", COMP_TYPE_FOOTPRINT, PRINTSHAPE_COMP_CID) |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
ParamBlockDesc2 gPrintShapeBk |
|
( |
|
plComponent::kBlkComp, _T("PrintShape"), 0, &gPrintShapeCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, |
|
|
|
IDD_COMP_FP_PRINTSHAPE, IDS_COMP_FP_PRINTSHAPE, 0, 0, NULL, |
|
|
|
plPrintShapeComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.45, |
|
p_range, 0.1, 30.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_WIDTH, IDC_COMP_WIDTH_SPIN, 0.1, |
|
end, |
|
|
|
plPrintShapeComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.9, |
|
p_range, 0.1, 30.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_LENGTH, IDC_COMP_LENGTH_SPIN, 0.1, |
|
end, |
|
|
|
plPrintShapeComponent::kHeight, _T("Height"), TYPE_FLOAT, 0, 0, |
|
p_default, 1.0, |
|
p_range, 0.1, 30.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_HEIGHT, IDC_COMP_HEIGHT_SPIN, 0.1, |
|
end, |
|
|
|
|
|
|
|
end |
|
); |
|
|
|
hsBool plPrintShapeComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
node->SetForceLocal(true); |
|
return true; |
|
} |
|
|
|
hsBool plPrintShapeComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
return true; |
|
} |
|
|
|
hsBool plPrintShapeComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
plSceneObject* obj = node->GetSceneObject(); |
|
if( !obj ) |
|
return true; |
|
|
|
plPrintShape* shape = TRACKED_NEW plPrintShape(); |
|
plKey shapeKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), shape, node->GetLocation()); |
|
|
|
shape->SetWidth(fCompPB->GetFloat(kWidth)); |
|
shape->SetLength(fCompPB->GetFloat(kLength)); |
|
shape->SetHeight(fCompPB->GetFloat(kHeight)); |
|
|
|
hsgResMgr::ResMgr()->AddViaNotify(shapeKey, TRACKED_NEW plObjRefMsg(obj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kInterface), plRefFlags::kActiveRef); |
|
|
|
return true; |
|
} |
|
|
|
plPrintShapeComponent::plPrintShapeComponent() |
|
{ |
|
fClassDesc = &gPrintShapeCompDesc; |
|
fClassDesc->MakeAutoParamBlocks(this); |
|
} |
|
|
|
plPrintShapeComponent::~plPrintShapeComponent() |
|
{ |
|
} |
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
const Class_ID ACTIVEPRINTSHAPE_COMP_CID(0x61b52046, 0x787734a5); |
|
|
|
class plActivePrintShapeComponent : public plComponent |
|
{ |
|
public: |
|
enum |
|
{ |
|
kWidth, |
|
kLength, |
|
kHeight, |
|
kNotifies |
|
}; |
|
protected: |
|
public: |
|
|
|
plActivePrintShapeComponent(); |
|
virtual ~plActivePrintShapeComponent(); |
|
void DeleteThis() { delete this; } |
|
|
|
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading |
|
// of properties on the MaxNode, as it's still indeterminant. |
|
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg); |
|
}; |
|
|
|
|
|
CLASS_DESC(plActivePrintShapeComponent, gActivePrintShapeCompDesc, "Active Shape", "ActiveShape", COMP_TYPE_FOOTPRINT, ACTIVEPRINTSHAPE_COMP_CID) |
|
|
|
|
|
class plActiveProc : public ParamMap2UserDlgProc |
|
{ |
|
public: |
|
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
|
{ |
|
switch (msg) |
|
{ |
|
case WM_INITDIALOG: |
|
{ |
|
} |
|
return true; |
|
|
|
case WM_COMMAND: |
|
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ADD_NOTIFY2) |
|
{ |
|
std::vector<Class_ID> cids; |
|
cids.push_back(FOOTPRINT_COMP_CID); |
|
cids.push_back(RIPPLE_COMP_CID); |
|
cids.push_back(PUDDLE_COMP_CID); |
|
cids.push_back(WAKE_COMP_CID); |
|
IParamBlock2 *pb = map->GetParamBlock(); |
|
plPick::Node(pb, plActivePrintShapeComponent::kNotifies, &cids, false, false); |
|
|
|
map->Invalidate(plActivePrintShapeComponent::kNotifies); |
|
return TRUE; |
|
} |
|
break; |
|
} |
|
|
|
return false; |
|
} |
|
void DeleteThis() {} |
|
}; |
|
static plActiveProc gActiveProc; |
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
|
ParamBlockDesc2 gActivePrintShapeBk |
|
( |
|
plComponent::kBlkComp, _T("ActivePrintShape"), 0, &gActivePrintShapeCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, |
|
|
|
IDD_COMP_FP_ACTIVEPRINTSHAPE, IDS_COMP_FP_ACTIVEPRINTSHAPE, 0, 0, &gActiveProc, |
|
|
|
plActivePrintShapeComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.45, |
|
p_range, 0.1, 30.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_WIDTH, IDC_COMP_WIDTH_SPIN, 0.1, |
|
end, |
|
|
|
plActivePrintShapeComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0, |
|
p_default, 0.9, |
|
p_range, 0.1, 30.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_LENGTH, IDC_COMP_LENGTH_SPIN, 0.1, |
|
end, |
|
|
|
plActivePrintShapeComponent::kHeight, _T("Height"), TYPE_FLOAT, 0, 0, |
|
p_default, 1.0, |
|
p_range, 0.1, 30.0, |
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT, |
|
IDC_COMP_HEIGHT, IDC_COMP_HEIGHT_SPIN, 0.1, |
|
end, |
|
|
|
plActivePrintShapeComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0, |
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS, |
|
end, |
|
|
|
end |
|
); |
|
|
|
hsBool plActivePrintShapeComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
node->SetForceLocal(true); |
|
return true; |
|
} |
|
|
|
hsBool plActivePrintShapeComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
return true; |
|
} |
|
|
|
hsBool plActivePrintShapeComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg) |
|
{ |
|
plSceneObject* obj = node->GetSceneObject(); |
|
if( !obj ) |
|
return true; |
|
|
|
plActivePrintShape* shape = TRACKED_NEW plActivePrintShape(); |
|
plKey shapeKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), shape, node->GetLocation()); |
|
|
|
shape->SetWidth(fCompPB->GetFloat(kWidth)); |
|
shape->SetLength(fCompPB->GetFloat(kLength)); |
|
shape->SetHeight(fCompPB->GetFloat(kHeight)); |
|
|
|
int num = fCompPB->Count(kNotifies); |
|
int i; |
|
for( i = 0; i < num; i++ ) |
|
{ |
|
plDynaDecalMgr* notify = plFootPrintComponent::GetDecalMgr(fCompPB->GetINode(kNotifies, TimeValue(0), i)); |
|
if( notify ) |
|
{ |
|
shape->AddDecalKey(notify->GetKey()); |
|
} |
|
} |
|
|
|
|
|
hsgResMgr::ResMgr()->AddViaNotify(shapeKey, TRACKED_NEW plObjRefMsg(obj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kInterface), plRefFlags::kActiveRef); |
|
|
|
return true; |
|
} |
|
|
|
plActivePrintShapeComponent::plActivePrintShapeComponent() |
|
{ |
|
fClassDesc = &gActivePrintShapeCompDesc; |
|
fClassDesc->MakeAutoParamBlocks(this); |
|
} |
|
|
|
plActivePrintShapeComponent::~plActivePrintShapeComponent() |
|
{ |
|
} |
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
|