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.
805 lines
24 KiB
805 lines
24 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 "MaxMain/plMaxNode.h" |
|
#include "MaxExport/plExportProgressBar.h" |
|
|
|
#include "HeadSpin.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); |
|
} |
|
|
|
|
|
|