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.
806 lines
22 KiB
806 lines
22 KiB
4 years ago
|
/*==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 "../MaxMain/plMaxNode.h"
|
||
|
#include "../MaxExport/plExportProgressBar.h"
|
||
|
|
||
|
#include "hsTypes.h"
|
||
|
|
||
|
#include "plLODFadeComponent.h"
|
||
|
|
||
|
#include "../pfSurface/plFadeOpacityMod.h"
|
||
|
#include "../pfSurface/plDistOpacityMod.h"
|
||
|
|
||
|
void DummyCodeIncludeFuncLODFade()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// LODFadeComponent first, similar and related BlendOnto component further on in file.
|
||
|
CLASS_DESC(plLODFadeComponent, gLODFadeCompDesc, "LOD Blend", "LODBlend", COMP_TYPE_GRAPHICS, LODFADE_COMP_CID)
|
||
|
|
||
|
ParamBlockDesc2 gLODFadeBk
|
||
|
(
|
||
|
plComponent::kBlkComp, _T("LODFade"), 0, &gLODFadeCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
|
||
|
|
||
|
IDD_COMP_LODFADE, IDS_COMP_LODFADE, 0, 0, NULL,
|
||
|
|
||
|
plLODFadeComponent::kHasBase, _T("HasBase"), TYPE_BOOL, 0, 0,
|
||
|
p_default, FALSE,
|
||
|
p_ui, TYPE_SINGLECHEKBOX, IDC_COMP_LODFADE_HASBASE,
|
||
|
end,
|
||
|
|
||
|
plLODFadeComponent::kBase, _T("Base"), TYPE_INODE, 0, 0,
|
||
|
p_ui, TYPE_PICKNODEBUTTON, IDC_COMP_LODFADE_BASE,
|
||
|
p_prompt, IDS_COMP_LODFADE_BASE,
|
||
|
end,
|
||
|
|
||
|
plLODFadeComponent::kDistance, _T("Distance"), TYPE_FLOAT, 0, 0,
|
||
|
p_default, 50.0,
|
||
|
p_range, 0.0, 1000.0,
|
||
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
|
||
|
IDC_COMP_LODFADE_DISTANCE, IDC_COMP_LODFADE_DISTANCE_SPIN, 1.0,
|
||
|
end,
|
||
|
|
||
|
plLODFadeComponent::kTransition, _T("Transition"), TYPE_FLOAT, 0, 0,
|
||
|
p_default, 10.0,
|
||
|
p_range, 0.0, 100.0,
|
||
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
|
||
|
IDC_COMP_LODFADE_TRANSITION, IDC_COMP_LODFADE_TRANSITION_SPIN, 1.0,
|
||
|
end,
|
||
|
|
||
|
plLODFadeComponent::kFadeBase, _T("FadeBase"), TYPE_BOOL, 0, 0,
|
||
|
p_default, FALSE,
|
||
|
p_ui, TYPE_SINGLECHEKBOX, IDC_COMP_LODFADE_FADEBASE,
|
||
|
p_enable_ctrls, 1, plLODFadeComponent::kBaseFirst,
|
||
|
end,
|
||
|
|
||
|
plLODFadeComponent::kBaseFirst, _T("BaseFirst"), TYPE_BOOL, 0, 0,
|
||
|
p_default, FALSE,
|
||
|
p_ui, TYPE_SINGLECHEKBOX, IDC_COMP_LODFADE_BASEFIRST,
|
||
|
end,
|
||
|
|
||
|
|
||
|
end
|
||
|
);
|
||
|
|
||
|
void plLODFadeComponent::ISetToFadeBase(plMaxNode* node, plMaxNode* base, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
if( fCompPB->GetInt(kBaseFirst) )
|
||
|
node->AddRenderDependency(base);
|
||
|
else
|
||
|
base->AddRenderDependency(node);
|
||
|
|
||
|
Box3 fade = base->GetFade();
|
||
|
Point3 maxs = fade.Max();
|
||
|
float fadeInStart = fCompPB->GetFloat(kDistance) - fCompPB->GetFloat(kTransition);
|
||
|
if( fadeInStart < 0 )
|
||
|
fadeInStart = 0;
|
||
|
float fadeInEnd = fCompPB->GetFloat(kDistance);
|
||
|
Point3 mins(fadeInStart, fadeInEnd, -1.f);
|
||
|
fade = Box3(mins, maxs);
|
||
|
base->SetFade(fade);
|
||
|
|
||
|
node->SetNoDeferDraw(true);
|
||
|
base->SetNoDeferDraw(true);
|
||
|
}
|
||
|
|
||
|
hsBool plLODFadeComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
if( fCompPB->GetInt(kHasBase) )
|
||
|
{
|
||
|
plMaxNode* base = (plMaxNode*)fCompPB->GetINode(kBase, TimeValue(0));
|
||
|
if( base )
|
||
|
{
|
||
|
if( fCompPB->GetInt(kFadeBase) )
|
||
|
{
|
||
|
ISetToFadeBase(node, base, pErrMsg);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
node->AddRenderDependency(base);
|
||
|
node->SetNoDeferDraw(true);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
Box3 fade = node->GetFade();
|
||
|
Point3 mins = fade.Min();
|
||
|
float fadeOutStart = fCompPB->GetFloat(kDistance);
|
||
|
float fadeOutEnd = fadeOutStart + fCompPB->GetFloat(kTransition);
|
||
|
Point3 maxs(fadeOutEnd, fadeOutStart, 1.f);
|
||
|
fade = Box3(mins, maxs);
|
||
|
node->SetFade(fade);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plLODFadeComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plLODFadeComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
plLODFadeComponent::plLODFadeComponent()
|
||
|
{
|
||
|
fClassDesc = &gLODFadeCompDesc;
|
||
|
fClassDesc->MakeAutoParamBlocks(this);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// BlendOnto component next.
|
||
|
CLASS_DESC(plBlendOntoComponent, gBlendOntoCompDesc, "Blend Onto", "BlendOnto", COMP_TYPE_GRAPHICS, BLENDONTO_COMP_CID)
|
||
|
|
||
|
ParamBlockDesc2 gBlendOntoBk
|
||
|
(
|
||
|
plComponent::kBlkComp, _T("BlendOnto"), 0, &gBlendOntoCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
|
||
|
|
||
|
IDD_COMP_BLENDONTO, IDS_COMP_BLENDONTO, 0, 0, NULL,
|
||
|
|
||
|
plBlendOntoComponent::kBaseNodes, _T("BaseNodes"), TYPE_INODE_TAB, 0, P_CAN_CONVERT, 0,
|
||
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, IDC_ADD_TARGS, 0, IDC_DEL_TARGS,
|
||
|
p_classID, triObjectClassID,
|
||
|
end,
|
||
|
|
||
|
plBlendOntoComponent::kSortFaces, _T("SortFaces"), TYPE_BOOL, 0, 0,
|
||
|
p_default, TRUE,
|
||
|
p_ui, TYPE_SINGLECHEKBOX, IDC_COMP_BLENDONTO_SORTFACES,
|
||
|
end,
|
||
|
|
||
|
|
||
|
end
|
||
|
);
|
||
|
|
||
|
hsBool plBlendOntoComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
hsBool someBase = false;
|
||
|
int numBase = fCompPB->Count(kBaseNodes);
|
||
|
int i;
|
||
|
for( i = 0; i < numBase; i++ )
|
||
|
{
|
||
|
plMaxNode* base = (plMaxNode*)fCompPB->GetINode(kBaseNodes, TimeValue(0), i);
|
||
|
|
||
|
if( base )
|
||
|
{
|
||
|
node->AddRenderDependency(base);
|
||
|
node->SetNoDeferDraw(true);
|
||
|
if( !fCompPB->GetInt(kSortFaces) )
|
||
|
node->SetNoFaceSort(true);
|
||
|
|
||
|
someBase = true;
|
||
|
}
|
||
|
}
|
||
|
if( !someBase )
|
||
|
{
|
||
|
node->SetBlendToFB(true);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plBlendOntoComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plBlendOntoComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
plBlendOntoComponent::plBlendOntoComponent()
|
||
|
{
|
||
|
fClassDesc = &gBlendOntoCompDesc;
|
||
|
fClassDesc->MakeAutoParamBlocks(this);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// BlendOntoAdv component next.
|
||
|
CLASS_DESC(plBlendOntoAdvComponent, gBlendOntoAdvCompDesc, "Blend Onto Advanced", "BlendOntoAdv", COMP_TYPE_GRAPHICS, BLENDONTOADV_COMP_CID)
|
||
|
|
||
|
ParamBlockDesc2 gBlendOntoAdvBk
|
||
|
(
|
||
|
plComponent::kBlkComp, _T("BlendOntoAdv"), 0, &gBlendOntoAdvCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
|
||
|
|
||
|
IDD_COMP_BLENDONTOADV, IDS_COMP_BLENDONTOADV, 0, 0, NULL,
|
||
|
|
||
|
plBlendOntoAdvComponent::kBaseNodes, _T("BaseNodes"), TYPE_INODE_TAB, 0, P_CAN_CONVERT, 0,
|
||
|
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, IDC_ADD_TARGS, 0, IDC_DEL_TARGS,
|
||
|
p_classID, triObjectClassID,
|
||
|
end,
|
||
|
|
||
|
plBlendOntoAdvComponent::kSortFaces, _T("SortFaces"), TYPE_BOOL, 0, 0,
|
||
|
p_default, TRUE,
|
||
|
p_ui, TYPE_SINGLECHEKBOX, IDC_COMP_BLENDONTOADV_SORTFACES,
|
||
|
end,
|
||
|
|
||
|
plBlendOntoAdvComponent::kSortObjects, _T("SortObjects"), TYPE_BOOL, 0, 0,
|
||
|
p_default, FALSE,
|
||
|
p_ui, TYPE_SINGLECHEKBOX, IDC_COMP_BLENDONTOADV_SORTOBJECTS,
|
||
|
end,
|
||
|
|
||
|
plBlendOntoAdvComponent::kOntoBlending, _T("OntoBlending"), TYPE_BOOL, 0, 0,
|
||
|
p_default, FALSE,
|
||
|
p_ui, TYPE_SINGLECHEKBOX, IDC_COMP_BLENDONTOADV_ONTOBLENDING,
|
||
|
end,
|
||
|
|
||
|
|
||
|
end
|
||
|
);
|
||
|
|
||
|
hsBool plBlendOntoAdvComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
hsBool someBase = false;
|
||
|
int numBase = fCompPB->Count(kBaseNodes);
|
||
|
int i;
|
||
|
for( i = 0; i < numBase; i++ )
|
||
|
{
|
||
|
plMaxNode* base = (plMaxNode*)fCompPB->GetINode(kBaseNodes, TimeValue(0), i);
|
||
|
|
||
|
if( base )
|
||
|
{
|
||
|
node->AddRenderDependency(base);
|
||
|
if( !fCompPB->GetInt(kOntoBlending) )
|
||
|
node->SetNoDeferDraw(true);
|
||
|
if( !fCompPB->GetInt(kSortFaces) )
|
||
|
node->SetNoFaceSort(true);
|
||
|
|
||
|
someBase = true;
|
||
|
}
|
||
|
}
|
||
|
if( !someBase )
|
||
|
{
|
||
|
node->SetBlendToFB(true);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plBlendOntoAdvComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plBlendOntoAdvComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
plBlendOntoAdvComponent::plBlendOntoAdvComponent()
|
||
|
{
|
||
|
fClassDesc = &gBlendOntoAdvCompDesc;
|
||
|
fClassDesc->MakeAutoParamBlocks(this);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Force drawing before the avatar.
|
||
|
|
||
|
const Class_ID B4AV_COMP_CID(0x14536d5b, 0x17dc623b);
|
||
|
|
||
|
class plB4AvComponent : public plComponent
|
||
|
{
|
||
|
public:
|
||
|
plB4AvComponent();
|
||
|
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(plB4AvComponent, gB4AvCompDesc, "Draw B4 Avatar", "B4Av", COMP_TYPE_GRAPHICS, B4AV_COMP_CID)
|
||
|
|
||
|
ParamBlockDesc2 gB4AvBk
|
||
|
(
|
||
|
plComponent::kBlkComp, _T("B4Av"), 0, &gB4AvCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
|
||
|
|
||
|
IDD_COMP_SORT_AS_OPAQUE, IDS_COMP_SORT_AS_OPAQUE, 0, 0, NULL,
|
||
|
|
||
|
end
|
||
|
);
|
||
|
|
||
|
hsBool plB4AvComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
node->SetSortAsOpaque(true);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plB4AvComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plB4AvComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
plB4AvComponent::plB4AvComponent()
|
||
|
{
|
||
|
fClassDesc = &gB4AvCompDesc;
|
||
|
fClassDesc->MakeAutoParamBlocks(this);
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// DistFadeComponent - just feeding them a bit more rope.
|
||
|
CLASS_DESC(plDistFadeComponent, gDistFadeCompDesc, "Distance Fade", "DistFade", COMP_TYPE_GRAPHICS, DISTFADE_COMP_CID)
|
||
|
|
||
|
ParamBlockDesc2 gDistFadeBk
|
||
|
(
|
||
|
plComponent::kBlkComp, _T("DistFade"), 0, &gDistFadeCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
|
||
|
|
||
|
IDD_COMP_DISTFADE, IDS_COMP_DISTFADE, 0, 0, NULL,
|
||
|
|
||
|
plDistFadeComponent::kFadeInActive, _T("FadeInActive"), TYPE_BOOL, 0, 0,
|
||
|
p_default, FALSE,
|
||
|
p_ui, TYPE_SINGLECHEKBOX, IDC_COMP_DISTFADE_IN_ACTIVE,
|
||
|
p_enable_ctrls, 2, plDistFadeComponent::kFadeInStart, plDistFadeComponent::kFadeInEnd,
|
||
|
end,
|
||
|
|
||
|
plDistFadeComponent::kFadeInStart, _T("FadeInStart"), TYPE_FLOAT, 0, 0,
|
||
|
p_default, 5.0,
|
||
|
p_range, 0.0, 1000.0,
|
||
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
|
||
|
IDC_COMP_DISTFADE_INSTART, IDC_COMP_DISTFADE_INSTART_SPIN, 1.0,
|
||
|
end,
|
||
|
|
||
|
plDistFadeComponent::kFadeInEnd, _T("FadeInEnd"), TYPE_FLOAT, 0, 0,
|
||
|
p_default, 10.0,
|
||
|
p_range, 0.0, 1000.0,
|
||
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
|
||
|
IDC_COMP_DISTFADE_INEND, IDC_COMP_DISTFADE_INEND_SPIN, 1.0,
|
||
|
end,
|
||
|
|
||
|
plDistFadeComponent::kFadeOutActive, _T("FadeOutActive"), TYPE_BOOL, 0, 0,
|
||
|
p_default, FALSE,
|
||
|
p_ui, TYPE_SINGLECHEKBOX, IDC_COMP_DISTFADE_OUT_ACTIVE,
|
||
|
p_enable_ctrls, 2, plDistFadeComponent::kFadeOutStart, plDistFadeComponent::kFadeOutEnd,
|
||
|
end,
|
||
|
|
||
|
plDistFadeComponent::kFadeOutStart, _T("FadeOutStart"), TYPE_FLOAT, 0, 0,
|
||
|
p_default, 50.0,
|
||
|
p_range, 0.0, 1000.0,
|
||
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
|
||
|
IDC_COMP_DISTFADE_OUTSTART, IDC_COMP_DISTFADE_OUTSTART_SPIN, 1.0,
|
||
|
end,
|
||
|
|
||
|
plDistFadeComponent::kFadeOutEnd, _T("FadeOutEnd"), TYPE_FLOAT, 0, 0,
|
||
|
p_default, 100.0,
|
||
|
p_range, 0.0, 1000.0,
|
||
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
|
||
|
IDC_COMP_DISTFADE_OUTEND, IDC_COMP_DISTFADE_OUTEND_SPIN, 1.0,
|
||
|
end,
|
||
|
|
||
|
|
||
|
end
|
||
|
);
|
||
|
|
||
|
hsBool plDistFadeComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
// If we're turned off, just return.
|
||
|
if( !fCompPB->GetInt(kFadeInActive) && !fCompPB->GetInt(kFadeOutActive) )
|
||
|
return true;
|
||
|
|
||
|
Box3 fade;
|
||
|
Point3 mins(0.f, 0.f, 0.f);
|
||
|
Point3 maxs(0.f, 0.f, 0.f);
|
||
|
|
||
|
|
||
|
if( fCompPB->GetInt(kFadeInActive) )
|
||
|
{
|
||
|
mins[0] = fCompPB->GetFloat(kFadeInStart);
|
||
|
mins[1] = fCompPB->GetFloat(kFadeInEnd);
|
||
|
}
|
||
|
if( fCompPB->GetInt(kFadeOutActive) )
|
||
|
{
|
||
|
maxs[0] = fCompPB->GetFloat(kFadeOutStart);
|
||
|
maxs[1] = fCompPB->GetFloat(kFadeOutEnd);
|
||
|
}
|
||
|
|
||
|
// We're not really sure how the artist has artistically interpreted
|
||
|
// the parameters. What we want is:
|
||
|
// Nearest point where object starts to fade in == mins[0]
|
||
|
// Nearest point where object is opaque == mins[1]
|
||
|
// Farthest point where object is opaque == maxs[1]
|
||
|
// Farthest point where object fades out completely = maxs[0]
|
||
|
//
|
||
|
// If the artist says they want it to start off opaque, fade out, then
|
||
|
// fade back in once it's far away, we'll explain in person why that's stupid,
|
||
|
// and in the meantime prevent them from doing that by assuming they just
|
||
|
// have the parameter order flipped.
|
||
|
//
|
||
|
// So, they've either given us 2 distances or 2 pairs of distances.
|
||
|
// If they've just given 2 distances, we use as is,
|
||
|
// but if they've given 2 pairs, we have to arrange them to fit the
|
||
|
// above model.
|
||
|
//
|
||
|
// So first thing to do is figure out how many (valid) distances we have.
|
||
|
if( (mins[0] == 0) && (mins[1] == 0) && (maxs[0] == 0) && (maxs[1] == 0) )
|
||
|
{
|
||
|
// Okay, they gave no valid distances. Just pretend we were never here.
|
||
|
return true;
|
||
|
}
|
||
|
if( (mins[0] == 0) && (mins[1] == 0) )
|
||
|
{
|
||
|
// maxs must be valid, just go with them.
|
||
|
fade = IFadeFromPoint(maxs);
|
||
|
}
|
||
|
else if( (maxs[0] == 0) && (maxs[1] == 0) )
|
||
|
{
|
||
|
// mins must be valid, just go with them.
|
||
|
fade = IFadeFromPoint(mins);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// They're both "valid". Give it a shot.
|
||
|
fade = IFadeFromPair(mins, maxs);
|
||
|
}
|
||
|
|
||
|
node->SetFade(fade);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void plDistFadeComponent::ISwap(float& p0, float& p1)
|
||
|
{
|
||
|
float t = p0;
|
||
|
p0 = p1;
|
||
|
p1 = t;
|
||
|
}
|
||
|
|
||
|
Box3 plDistFadeComponent::IFadeFromPoint(Point3& mins)
|
||
|
{
|
||
|
Point3 maxs(0.f, 0.f, 0.f);
|
||
|
if( mins[0] < mins[1] )
|
||
|
mins[2] = -1.f;
|
||
|
else if( mins[0] > mins[1] )
|
||
|
mins[2] = 1.f;
|
||
|
else
|
||
|
mins[2] = 0;
|
||
|
|
||
|
return Box3(mins, maxs);
|
||
|
}
|
||
|
|
||
|
Box3 plDistFadeComponent::IFadeFromPair(Point3& mins, Point3& maxs)
|
||
|
{
|
||
|
if( mins[0] > maxs[0] )
|
||
|
{
|
||
|
ISwap(mins[0], maxs[0]);
|
||
|
ISwap(mins[1], maxs[1]);
|
||
|
}
|
||
|
if( mins[0] > mins[1] )
|
||
|
{
|
||
|
ISwap(mins[0], mins[1]);
|
||
|
}
|
||
|
if( maxs[0] < maxs[1] )
|
||
|
{
|
||
|
// Poor confused bastard, take a guess what he wants.
|
||
|
ISwap(maxs[0], maxs[1]);
|
||
|
}
|
||
|
if( mins[0] < mins[1] )
|
||
|
mins[2] = -1.f;
|
||
|
else
|
||
|
mins[2] = 0;
|
||
|
if( maxs[0] > maxs[1] )
|
||
|
maxs[2] = 1.f;
|
||
|
else
|
||
|
maxs[2] = 0;
|
||
|
return Box3(mins, maxs);
|
||
|
}
|
||
|
|
||
|
|
||
|
hsBool plDistFadeComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plDistFadeComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
plDistFadeComponent::plDistFadeComponent()
|
||
|
{
|
||
|
fClassDesc = &gDistFadeCompDesc;
|
||
|
fClassDesc->MakeAutoParamBlocks(this);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// LOS Fade component next.
|
||
|
|
||
|
class plLOSFadeComponent : public plComponent
|
||
|
{
|
||
|
public:
|
||
|
enum
|
||
|
{
|
||
|
kBoundsCenter,
|
||
|
kFadeInTime,
|
||
|
kFadeOutTime
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
plLOSFadeComponent();
|
||
|
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(plLOSFadeComponent, gLOSFadeCompDesc, "LOS Fade", "LOSFade", COMP_TYPE_GRAPHICS, LOSFADE_COMP_CID)
|
||
|
|
||
|
ParamBlockDesc2 gLOSFadeBk
|
||
|
(
|
||
|
plComponent::kBlkComp, _T("LOSFade"), 0, &gLOSFadeCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
|
||
|
|
||
|
IDD_COMP_LOSFADE, IDS_COMP_LOSFADE, 0, 0, NULL,
|
||
|
|
||
|
plLOSFadeComponent::kBoundsCenter, _T("BoundsCenter"), TYPE_BOOL, 0, 0,
|
||
|
p_default, FALSE,
|
||
|
p_ui, TYPE_SINGLECHEKBOX, IDC_COMP_BOUNDSCENTER,
|
||
|
end,
|
||
|
|
||
|
plLOSFadeComponent::kFadeInTime, _T("kFadeInTime"), TYPE_FLOAT, 0, 0,
|
||
|
p_default, 0.5,
|
||
|
p_range, 0.0, 5.0,
|
||
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
|
||
|
IDC_COMP_FADEINTIME, IDC_COMP_FADEINTIME_SPIN, 1.0,
|
||
|
end,
|
||
|
|
||
|
|
||
|
plLOSFadeComponent::kFadeOutTime, _T("kFadeOutTime"), TYPE_FLOAT, 0, 0,
|
||
|
p_default, 1.0,
|
||
|
p_range, 0.0, 5.0,
|
||
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
|
||
|
IDC_COMP_FADEOUTTIME, IDC_COMP_FADEOUTTIME_SPIN, 1.0,
|
||
|
end,
|
||
|
|
||
|
|
||
|
end
|
||
|
);
|
||
|
|
||
|
hsBool plLOSFadeComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
node->SetForceMatShade(true);
|
||
|
node->SetForceLocal(true);
|
||
|
node->SetForceMaterialCopy(true);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plLOSFadeComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plLOSFadeComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
plFadeOpacityMod* fade = TRACKED_NEW plFadeOpacityMod;
|
||
|
|
||
|
if( fCompPB->GetInt(kBoundsCenter) )
|
||
|
fade->SetFlag(plFadeOpacityMod::kBoundsCenter);
|
||
|
else
|
||
|
fade->ClearFlag(plFadeOpacityMod::kBoundsCenter);
|
||
|
|
||
|
fade->SetFadeUp(fCompPB->GetFloat(kFadeInTime));
|
||
|
fade->SetFadeDown(fCompPB->GetFloat(kFadeOutTime));
|
||
|
|
||
|
node->AddModifier(fade, node->GetKey()->GetName());
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
plLOSFadeComponent::plLOSFadeComponent()
|
||
|
{
|
||
|
fClassDesc = &gLOSFadeCompDesc;
|
||
|
fClassDesc->MakeAutoParamBlocks(this);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// GZ Marker Fade component next.
|
||
|
|
||
|
const Class_ID GZFADE_COMP_CID(0x27173270, 0x4f4486f);
|
||
|
|
||
|
class plGZFadeComponent : public plComponent
|
||
|
{
|
||
|
public:
|
||
|
enum
|
||
|
{
|
||
|
kOpaque,
|
||
|
kTransp
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
plGZFadeComponent();
|
||
|
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(plGZFadeComponent, gGZFadeCompDesc, "GZ Fade", "GZFade", COMP_TYPE_GRAPHICS, GZFADE_COMP_CID)
|
||
|
|
||
|
ParamBlockDesc2 gGZFadeBk
|
||
|
(
|
||
|
plComponent::kBlkComp, _T("GZFade"), 0, &gGZFadeCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
|
||
|
|
||
|
IDD_COMP_GZFADE, IDS_COMP_GZ_FADE, 0, 0, NULL,
|
||
|
|
||
|
plGZFadeComponent::kOpaque, _T("kOpaque"), TYPE_FLOAT, 0, 0,
|
||
|
p_default, 15.0,
|
||
|
p_range, 0.0, 100.0,
|
||
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
|
||
|
IDC_COMP_GZ_OPAQUE, IDC_COMP_GZ_OPAQUE_SPIN, 1.0,
|
||
|
end,
|
||
|
|
||
|
plGZFadeComponent::kTransp, _T("kTransp"), TYPE_FLOAT, 0, 0,
|
||
|
p_default, 20.0,
|
||
|
p_range, 0.0, 100.0,
|
||
|
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
|
||
|
IDC_COMP_GZ_TRANSP, IDC_COMP_GZ_TRANSP_SPIN, 1.0,
|
||
|
end,
|
||
|
|
||
|
|
||
|
end
|
||
|
);
|
||
|
|
||
|
hsBool plGZFadeComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
float opaq = fCompPB->GetFloat(kOpaque);
|
||
|
float transp = fCompPB->GetFloat(kTransp);
|
||
|
|
||
|
pErrMsg->Set(transp <= opaq, node->GetName(), "Distance obj goes transparent must be greater than distance it's opaque").CheckAndAsk();
|
||
|
pErrMsg->Set(false);
|
||
|
|
||
|
node->SetForceMatShade(true);
|
||
|
node->SetForceLocal(true);
|
||
|
node->SetForceMaterialCopy(true);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plGZFadeComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plGZFadeComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
plDistOpacityMod* fade = TRACKED_NEW plDistOpacityMod;
|
||
|
|
||
|
float opaq = fCompPB->GetFloat(kOpaque);
|
||
|
float transp = fCompPB->GetFloat(kTransp);
|
||
|
|
||
|
fade->SetFarDist(opaq, transp);
|
||
|
|
||
|
node->AddModifier(fade, node->GetKey()->GetName());
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
plGZFadeComponent::plGZFadeComponent()
|
||
|
{
|
||
|
fClassDesc = &gGZFadeCompDesc;
|
||
|
fClassDesc->MakeAutoParamBlocks(this);
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Force dynamic material - keeps the material colors from getting burnt into the verts.
|
||
|
|
||
|
const Class_ID DYNMAT_COMP_CID(0x2ea4671f, 0x163b12ac);
|
||
|
|
||
|
class plDynMatComponent : public plComponent
|
||
|
{
|
||
|
public:
|
||
|
enum
|
||
|
{
|
||
|
kOpaque,
|
||
|
kTransp
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
plDynMatComponent();
|
||
|
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(plDynMatComponent, gDynMatCompDesc, "Force Dyn Mat", "DynMat", COMP_TYPE_GRAPHICS, DYNMAT_COMP_CID)
|
||
|
|
||
|
ParamBlockDesc2 gDynMatBk
|
||
|
(
|
||
|
plComponent::kBlkComp, _T("DynMat"), 0, &gDynMatCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
|
||
|
|
||
|
IDD_COMP_DYNMAT, IDS_COMP_DYNMAT, 0, 0, NULL,
|
||
|
|
||
|
end
|
||
|
);
|
||
|
|
||
|
hsBool plDynMatComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
node->SetForceMatShade(true);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plDynMatComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
hsBool plDynMatComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
plDynMatComponent::plDynMatComponent()
|
||
|
{
|
||
|
fClassDesc = &gDynMatCompDesc;
|
||
|
fClassDesc->MakeAutoParamBlocks(this);
|
||
|
}
|
||
|
|
||
|
|