mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
Initial Commit of CyanWorlds.com Engine Open Source Client/Plugin
This commit is contained in:
@ -0,0 +1,492 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plAngleAttenLayer.h"
|
||||
|
||||
#include "iparamb2.h"
|
||||
#include "iparamm2.h"
|
||||
#include "stdmat.h"
|
||||
|
||||
#include "plBMSampler.h"
|
||||
#include "../MaxMain/plPlasmaRefMsgs.h"
|
||||
|
||||
class plAngleAttenLayerClassDesc : public ClassDesc2
|
||||
{
|
||||
public:
|
||||
int IsPublic() { return TRUE; }
|
||||
void* Create(BOOL loading = FALSE) { return TRACKED_NEW plAngleAttenLayer(); }
|
||||
const TCHAR* ClassName() { return GetString(IDS_ANGLE_ATTEN_LAYER); }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
Class_ID ClassID() { return ANGLE_ATTEN_LAYER_CLASS_ID; }
|
||||
const TCHAR* Category() { return TEXMAP_CAT_COLMOD; }
|
||||
const TCHAR* InternalName() { return _T("PlasmaAngleAttenLayer"); }
|
||||
HINSTANCE HInstance() { return hInstance; }
|
||||
};
|
||||
static plAngleAttenLayerClassDesc plAngleAttenLayerDesc;
|
||||
ClassDesc2* GetAngleAttenLayerDesc() { return &plAngleAttenLayerDesc; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// ParamBlock Definition ////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const float kDefTransp0 = 60.f;
|
||||
static const float kDefOpaque0 = 90.f;
|
||||
static const float kDefTransp1 = 30.f;
|
||||
static const float kDefOpaque1 = 0.f;
|
||||
|
||||
static ParamBlockDesc2 gAngleAttenParamBlk
|
||||
(
|
||||
plAngleAttenLayer::kBlkAngles, _T("angles"), 0, GetAngleAttenLayerDesc(),//NULL,
|
||||
P_AUTO_CONSTRUCT + P_AUTO_UI, plAngleAttenLayer::kRefAngles,
|
||||
|
||||
IDD_ANGLE_ATTEN_LAYER, IDS_ANGLE_ATTEN_LAYER_PROPS, 0, 0, nil,
|
||||
|
||||
// Texture size
|
||||
plAngleAttenLayer::kTranspAngle0, _T("transp0"), TYPE_FLOAT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_TRANSP_ANGLE_0, IDC_TRANSP_ANGLE_0_SPIN, SPIN_AUTOSCALE,
|
||||
p_range, 0.0, 180.0,
|
||||
p_default, kDefTransp0,
|
||||
end,
|
||||
|
||||
plAngleAttenLayer::kOpaqueAngle0, _T("opaque0"), TYPE_FLOAT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_OPAQUE_ANGLE_0, IDC_OPAQUE_ANGLE_0_SPIN, SPIN_AUTOSCALE,
|
||||
p_range, 0.0, 180.0,
|
||||
p_default, kDefOpaque0,
|
||||
end,
|
||||
|
||||
plAngleAttenLayer::kDoubleFade, _T("doubleFade"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_DOUBLE_FADE,
|
||||
p_enable_ctrls, 2, plAngleAttenLayer::kOpaqueAngle1, plAngleAttenLayer::kTranspAngle1,
|
||||
p_default, false,
|
||||
end,
|
||||
|
||||
plAngleAttenLayer::kOpaqueAngle1, _T("opaque1"), TYPE_FLOAT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_OPAQUE_ANGLE_1, IDC_OPAQUE_ANGLE_1_SPIN, SPIN_AUTOSCALE,
|
||||
p_range, 0.0, 180.0,
|
||||
p_default, kDefTransp1,
|
||||
end,
|
||||
|
||||
plAngleAttenLayer::kTranspAngle1, _T("transp1"), TYPE_FLOAT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_TRANSP_ANGLE_1, IDC_TRANSP_ANGLE_1_SPIN, SPIN_AUTOSCALE,
|
||||
p_range, 0.0, 180.0,
|
||||
p_default, kDefOpaque1,
|
||||
end,
|
||||
|
||||
plAngleAttenLayer::kReflect, _T("reflect"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_REFLECT,
|
||||
p_default, false,
|
||||
end,
|
||||
|
||||
plAngleAttenLayer::kLoClamp, _T("loClamp"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_LO_CLAMP, IDC_LO_CLAMP_SPIN, SPIN_AUTOSCALE,
|
||||
p_range, 0, 100,
|
||||
p_default, 0,
|
||||
end,
|
||||
|
||||
plAngleAttenLayer::kHiClamp, _T("hiClamp"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_HI_CLAMP, IDC_HI_CLAMP_SPIN, SPIN_AUTOSCALE,
|
||||
p_range, 0, 100,
|
||||
p_default, 100,
|
||||
end,
|
||||
|
||||
end
|
||||
);
|
||||
|
||||
plAngleAttenLayer::plAngleAttenLayer() :
|
||||
fParmsPB(NULL),
|
||||
fIValid(NEVER),
|
||||
fCosTransp0(0),
|
||||
fCosOpaque0(0),
|
||||
fCosTransp1(0),
|
||||
fCosOpaque1(0),
|
||||
fCosinesCached(false)
|
||||
{
|
||||
plAngleAttenLayerDesc.MakeAutoParamBlocks(this);
|
||||
}
|
||||
|
||||
plAngleAttenLayer::~plAngleAttenLayer()
|
||||
{
|
||||
}
|
||||
|
||||
//From MtlBase
|
||||
void plAngleAttenLayer::Reset()
|
||||
{
|
||||
GetAngleAttenLayerDesc()->Reset(this, TRUE); // reset all pb2's
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
|
||||
|
||||
fIValid.SetEmpty();
|
||||
}
|
||||
|
||||
void plAngleAttenLayer::Update(TimeValue t, Interval& valid)
|
||||
{
|
||||
if (!fIValid.InInterval(t))
|
||||
{
|
||||
fIValid.SetInfinite();
|
||||
|
||||
}
|
||||
|
||||
valid &= fIValid;
|
||||
}
|
||||
|
||||
Interval plAngleAttenLayer::Validity(TimeValue t)
|
||||
{
|
||||
//TODO: Update fIValid here
|
||||
|
||||
Interval v = FOREVER;
|
||||
return v;
|
||||
}
|
||||
|
||||
ParamDlg* plAngleAttenLayer::CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp)
|
||||
{
|
||||
IAutoMParamDlg* masterDlg = plAngleAttenLayerDesc.CreateParamDlgs(hwMtlEdit, imp, this);
|
||||
|
||||
return masterDlg;
|
||||
}
|
||||
|
||||
BOOL plAngleAttenLayer::SetDlgThing(ParamDlg* dlg)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int plAngleAttenLayer::NumRefs()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
//From ReferenceMaker
|
||||
RefTargetHandle plAngleAttenLayer::GetReference(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case kRefAngles: return fParmsPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void plAngleAttenLayer::SetReference(int i, RefTargetHandle rtarg)
|
||||
{
|
||||
Interval garbage;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case kRefAngles:
|
||||
fParmsPB = (IParamBlock2 *)rtarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int plAngleAttenLayer::NumParamBlocks()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
IParamBlock2* plAngleAttenLayer::GetParamBlock(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: return fParmsPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IParamBlock2* plAngleAttenLayer::GetParamBlockByID(BlockID id)
|
||||
{
|
||||
if (fParmsPB->ID() == id)
|
||||
return fParmsPB;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//From ReferenceTarget
|
||||
RefTargetHandle plAngleAttenLayer::Clone(RemapDir &remap)
|
||||
{
|
||||
plAngleAttenLayer *mnew = TRACKED_NEW plAngleAttenLayer();
|
||||
*((MtlBase*)mnew) = *((MtlBase*)this); // copy superclass stuff
|
||||
mnew->ReplaceReference(kRefAngles, remap.CloneRef(fParmsPB));
|
||||
BaseClone(this, mnew, remap);
|
||||
return (RefTargetHandle)mnew;
|
||||
}
|
||||
|
||||
int plAngleAttenLayer::NumSubs()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Animatable* plAngleAttenLayer::SubAnim(int i)
|
||||
{
|
||||
//TODO: Return 'i-th' sub-anim
|
||||
switch (i)
|
||||
{
|
||||
case kRefAngles: return fParmsPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TSTR plAngleAttenLayer::SubAnimName(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case kRefAngles: return "Angles";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
RefResult plAngleAttenLayer::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case REFMSG_CHANGE:
|
||||
{
|
||||
fIValid.SetEmpty();
|
||||
|
||||
if (hTarget == fParmsPB)
|
||||
{
|
||||
// see if this message came from a changing parameter in the pblock,
|
||||
// if so, limit rollout update to the changing item
|
||||
ParamID changingParam = fParmsPB->LastNotifyParamID();
|
||||
fParmsPB->GetDesc()->InvalidateUI(changingParam);
|
||||
|
||||
if (changingParam != -1)
|
||||
IChanged();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return REF_SUCCEED;
|
||||
}
|
||||
|
||||
void plAngleAttenLayer::IChanged()
|
||||
{
|
||||
// Cut and paste insanity from DynamicTextLayer.
|
||||
// Texture wasn't getting updated in the viewports, and this fixes it.
|
||||
// Don't know if it's the right way though.
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
|
||||
|
||||
// And this is so the SceneWatcher gets notified that the material on some of it's
|
||||
// referenced objects changed.
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_USER_MAT);
|
||||
|
||||
ICacheCosines();
|
||||
}
|
||||
|
||||
void plAngleAttenLayer::ICacheCosines()
|
||||
{
|
||||
fCosTransp0 = cosf(DegToRad(fParmsPB->GetFloat(kTranspAngle0)));
|
||||
fCosOpaque0 = cosf(DegToRad(fParmsPB->GetFloat(kOpaqueAngle0)));
|
||||
|
||||
if( fParmsPB->GetInt(kDoubleFade) )
|
||||
{
|
||||
fCosTransp1 = cosf(DegToRad(fParmsPB->GetFloat(kTranspAngle1)));
|
||||
fCosOpaque1 = cosf(DegToRad(fParmsPB->GetFloat(kOpaqueAngle1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
fCosTransp1 = fCosOpaque1 = 0;
|
||||
}
|
||||
fCosinesCached = true;
|
||||
}
|
||||
|
||||
#define TEX_HDR_CHUNK 0x5000
|
||||
|
||||
IOResult plAngleAttenLayer::Save(ISave *isave)
|
||||
{
|
||||
IOResult res;
|
||||
|
||||
isave->BeginChunk(TEX_HDR_CHUNK);
|
||||
res = MtlBase::Save(isave);
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
isave->EndChunk();
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult plAngleAttenLayer::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
if (iload->CurChunkID() == TEX_HDR_CHUNK)
|
||||
{
|
||||
res = MtlBase::Load(iload);
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
|
||||
AColor plAngleAttenLayer::EvalColor(ShadeContext& sc)
|
||||
{
|
||||
if( !sc.doMaps )
|
||||
return AColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
AColor color;
|
||||
if (sc.GetCache(this, color))
|
||||
return color;
|
||||
|
||||
if( !fCosinesCached )
|
||||
ICacheCosines();
|
||||
|
||||
if (gbufID)
|
||||
sc.SetGBufferID(gbufID);
|
||||
|
||||
// Evaluate the Bitmap
|
||||
|
||||
Point3 normal = sc.Normal();
|
||||
|
||||
if( fParmsPB->GetInt(kReflect) )
|
||||
{
|
||||
normal = sc.ReflectVector();
|
||||
}
|
||||
float dotZ = normal.z;
|
||||
|
||||
float alpha = 1.f;
|
||||
if( fCosTransp0 != fCosOpaque0 )
|
||||
{
|
||||
float a = (dotZ - fCosTransp0) / (fCosOpaque0 - fCosTransp0);
|
||||
if( a < 0 )
|
||||
a = 0;
|
||||
else if( a > 1.f )
|
||||
a = 1.f;
|
||||
alpha *= a;
|
||||
}
|
||||
if( fParmsPB->GetInt(kDoubleFade) && (fCosTransp1 != fCosOpaque1) )
|
||||
{
|
||||
float a = (dotZ - fCosTransp1) / (fCosOpaque1 - fCosTransp1);
|
||||
if( a < 0 )
|
||||
a = 0;
|
||||
else if( a > 1.f )
|
||||
a = 1.f;
|
||||
if( fCosTransp0 < fCosTransp1 )
|
||||
{
|
||||
if( fCosTransp0 > fCosOpaque0 )
|
||||
alpha += a;
|
||||
else
|
||||
alpha *= a;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( fCosTransp0 < fCosOpaque0 )
|
||||
alpha += a;
|
||||
else
|
||||
alpha *= a;
|
||||
}
|
||||
}
|
||||
color = AColor(1.f, 1.f, 1.f, alpha);
|
||||
|
||||
sc.PutCache(this, color);
|
||||
return color;
|
||||
}
|
||||
|
||||
float plAngleAttenLayer::EvalMono(ShadeContext& sc)
|
||||
{
|
||||
return Intens(EvalColor(sc));
|
||||
}
|
||||
|
||||
Point3 plAngleAttenLayer::EvalNormalPerturb(ShadeContext& sc)
|
||||
{
|
||||
// Return the perturbation to apply to a normal for bump mapping
|
||||
return Point3(0, 0, 0);
|
||||
}
|
||||
|
||||
ULONG plAngleAttenLayer::LocalRequirements(int subMtlNum)
|
||||
{
|
||||
return MTLREQ_VIEW_DEP | MTLREQ_TRANSP;
|
||||
}
|
||||
|
||||
void plAngleAttenLayer::ActivateTexDisplay(BOOL onoff)
|
||||
{
|
||||
}
|
||||
|
||||
BITMAPINFO *plAngleAttenLayer::GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono, BOOL forceW, BOOL forceH)
|
||||
{
|
||||
return nil;
|
||||
// FIXME
|
||||
}
|
||||
|
||||
DWORD plAngleAttenLayer::GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *plAngleAttenLayer::GetTextureName( int which )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int plAngleAttenLayer::GetLoClamp()
|
||||
{
|
||||
return fParmsPB->GetInt(kLoClamp);
|
||||
}
|
||||
|
||||
int plAngleAttenLayer::GetHiClamp()
|
||||
{
|
||||
return fParmsPB->GetInt(kHiClamp);
|
||||
}
|
||||
|
||||
Box3 plAngleAttenLayer::GetFade()
|
||||
{
|
||||
Point3 pmin, pmax;
|
||||
|
||||
pmin.x = fParmsPB->GetFloat(kTranspAngle0);
|
||||
pmin.y = fParmsPB->GetFloat(kOpaqueAngle0);
|
||||
if( pmin.x < pmin.y )
|
||||
pmin.z = -1.f;
|
||||
else if( pmin.x > pmin.y )
|
||||
pmin.z = 1.f;
|
||||
else
|
||||
pmin.z = 0;
|
||||
|
||||
if( fParmsPB->GetInt(kDoubleFade) )
|
||||
{
|
||||
pmax.x = fParmsPB->GetFloat(kTranspAngle1);
|
||||
pmax.y = fParmsPB->GetFloat(kOpaqueAngle1);
|
||||
if( pmax.x < pmax.y )
|
||||
pmax.z = -1.f;
|
||||
else if( pmax.x > pmax.y )
|
||||
pmax.z = 1.f;
|
||||
else
|
||||
pmax.z = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pmax.x = pmax.y = pmax.z = 0;
|
||||
}
|
||||
return Box3(pmin, pmax);
|
||||
|
||||
}
|
||||
|
||||
BOOL plAngleAttenLayer::Reflect()
|
||||
{
|
||||
return fParmsPB->GetInt(kReflect);
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
|
||||
#ifndef plAngleAttenLayer_inc
|
||||
#define plAngleAttenLayer_inc
|
||||
|
||||
#include "Max.h"
|
||||
#include "../resource.h"
|
||||
#include "plPlasmaMAXLayer.h"
|
||||
|
||||
class ClassDesc2;
|
||||
class IParamBlock2;
|
||||
|
||||
ClassDesc2* GetAngleAttenLayerDesc();
|
||||
|
||||
extern TCHAR *GetString(int id);
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
|
||||
//// Class Definition /////////////////////////////////////////////////////////
|
||||
|
||||
class plAngleAttenLayer : public plPlasmaMAXLayer
|
||||
{
|
||||
protected:
|
||||
// Parameter block
|
||||
IParamBlock2* fParmsPB;
|
||||
|
||||
Interval fIValid;
|
||||
|
||||
BOOL fCosinesCached;
|
||||
float fCosTransp0;
|
||||
float fCosOpaque0;
|
||||
float fCosTransp1;
|
||||
float fCosOpaque1;
|
||||
|
||||
public:
|
||||
// Ref nums
|
||||
enum
|
||||
{
|
||||
kRefAngles
|
||||
};
|
||||
|
||||
// Block ID's
|
||||
enum
|
||||
{
|
||||
kBlkAngles
|
||||
};
|
||||
|
||||
plAngleAttenLayer();
|
||||
~plAngleAttenLayer();
|
||||
void DeleteThis() { delete this; }
|
||||
|
||||
//From MtlBase
|
||||
ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
|
||||
BOOL SetDlgThing(ParamDlg* dlg);
|
||||
void Update(TimeValue t, Interval& valid);
|
||||
void Reset();
|
||||
Interval Validity(TimeValue t);
|
||||
ULONG LocalRequirements(int subMtlNum);
|
||||
|
||||
//From Texmap
|
||||
RGBA EvalColor(ShadeContext& sc);
|
||||
float EvalMono(ShadeContext& sc);
|
||||
Point3 EvalNormalPerturb(ShadeContext& sc);
|
||||
|
||||
// For displaying textures in the viewport
|
||||
BOOL SupportTexDisplay() { return FALSE; }
|
||||
void ActivateTexDisplay(BOOL onoff);
|
||||
BITMAPINFO *GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono=FALSE, int forceW=0, int forceH=0);
|
||||
DWORD GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
|
||||
protected:
|
||||
void ICacheCosines();
|
||||
void IChanged();
|
||||
void IDiscardTexHandle();
|
||||
|
||||
public:
|
||||
|
||||
//TODO: Return anim index to reference index
|
||||
int SubNumToRefNum(int subNum) { return subNum; }
|
||||
|
||||
virtual BOOL DiscardColor() { return true; }
|
||||
|
||||
// Loading/Saving
|
||||
IOResult Load(ILoad *iload);
|
||||
IOResult Save(ISave *isave);
|
||||
|
||||
//From Animatable
|
||||
Class_ID ClassID() { return ANGLE_ATTEN_LAYER_CLASS_ID; }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
void GetClassName(TSTR& s) { s = GetString(IDS_ANGLE_ATTEN_LAYER); }
|
||||
|
||||
RefTargetHandle Clone( RemapDir &remap );
|
||||
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message);
|
||||
|
||||
int NumSubs();
|
||||
Animatable* SubAnim(int i);
|
||||
TSTR SubAnimName(int i);
|
||||
|
||||
// TODO: Maintain the number or references here
|
||||
int NumRefs();
|
||||
RefTargetHandle GetReference(int i);
|
||||
void SetReference(int i, RefTargetHandle rtarg);
|
||||
|
||||
int NumParamBlocks(); // return number of ParamBlocks in this instance
|
||||
IParamBlock2* GetParamBlock(int i); // return i'th ParamBlock
|
||||
IParamBlock2* GetParamBlockByID(BlockID id); // return id'd ParamBlock
|
||||
|
||||
const char *GetTextureName( int which );
|
||||
|
||||
|
||||
/// ParamBlock accessors
|
||||
enum
|
||||
{
|
||||
kTranspAngle0,
|
||||
kOpaqueAngle0,
|
||||
kOpaqueAngle1,
|
||||
kTranspAngle1,
|
||||
kDoubleFade,
|
||||
kReflect,
|
||||
kLoClamp,
|
||||
kHiClamp
|
||||
};
|
||||
|
||||
|
||||
// Pure virtual accessors for the various bitmap related elements
|
||||
virtual Bitmap *GetMaxBitmap(int index = 0) { hsAssert( false, "Function call not valid on this type of layer." ); return nil; }
|
||||
virtual PBBitmap *GetPBBitmap( int index = 0 ) { hsAssert( false, "Function call not valid on this type of layer." ); return nil; }
|
||||
virtual int GetNumBitmaps( void ) { return 0; }
|
||||
|
||||
// Some specific to processing this layer type into runtime materials.
|
||||
virtual Box3 GetFade();
|
||||
virtual BOOL Reflect();
|
||||
virtual int GetLoClamp();
|
||||
virtual int GetHiClamp();
|
||||
|
||||
protected:
|
||||
virtual void ISetMaxBitmap(Bitmap *bitmap, int index = 0) { hsAssert( false, "Function call not valid on this type of layer." ); }
|
||||
virtual void ISetPBBitmap( PBBitmap *pbbm, int index = 0 ){ hsAssert( false, "Function call not valid on this type of layer." ); }
|
||||
};
|
||||
|
||||
#endif // plAngleAttenLayer_inc
|
@ -0,0 +1,402 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plDynamicEnvLayer - Dynamic EnvironmentMap MAX Layer //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 8.22.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plDynamicEnvLayer.h"
|
||||
|
||||
#include "iparamb2.h"
|
||||
#include "iparamm2.h"
|
||||
#include "stdmat.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include "plBMSampler.h"
|
||||
#include "../MaxMain/plPlasmaRefMsgs.h"
|
||||
|
||||
|
||||
//// Externs //////////////////////////////////////////////////////////////////
|
||||
|
||||
extern TCHAR *GetString( int id );
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
//// ClassDesc Definition /////////////////////////////////////////////////////
|
||||
|
||||
class plDynamicEnvLayerClassDesc : public ClassDesc2
|
||||
{
|
||||
public:
|
||||
int IsPublic() { return TRUE; }
|
||||
void* Create(BOOL loading = FALSE) { return TRACKED_NEW plDynamicEnvLayer(); }
|
||||
const TCHAR* ClassName() { return GetString(IDS_DYNAMIC_ENVMAP_LAYER); }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
Class_ID ClassID() { return DYNAMIC_ENV_LAYER_CLASS_ID; }
|
||||
const TCHAR* Category() { return TEXMAP_CAT_ENV; }
|
||||
const TCHAR* InternalName() { return _T("PlasmaDynamicEnvMapLayer"); }
|
||||
HINSTANCE HInstance() { return hInstance; }
|
||||
};
|
||||
static plDynamicEnvLayerClassDesc plDynamicEnvLayerDesc;
|
||||
ClassDesc2* GetDynamicEnvLayerDesc() { return &plDynamicEnvLayerDesc; }
|
||||
|
||||
#include "plDynamicEnvLayerBitmapPB.cpp"
|
||||
|
||||
//// Constructor/Destructor ///////////////////////////////////////////////////
|
||||
|
||||
plDynamicEnvLayer::plDynamicEnvLayer() :
|
||||
fBitmapPB(NULL),
|
||||
fUVGen(NULL),
|
||||
fTexHandle(NULL),
|
||||
fTexTime(0),
|
||||
fIValid(NEVER)
|
||||
{
|
||||
plDynamicEnvLayerDesc.MakeAutoParamBlocks(this);
|
||||
ReplaceReference(kRefUVGen, GetNewDefaultUVGen());
|
||||
}
|
||||
|
||||
plDynamicEnvLayer::~plDynamicEnvLayer()
|
||||
{
|
||||
IDiscardTexHandle();
|
||||
}
|
||||
|
||||
void plDynamicEnvLayer::GetClassName( TSTR& s )
|
||||
{
|
||||
s = GetString( IDS_DYNAMIC_ENVMAP_LAYER );
|
||||
}
|
||||
|
||||
//// Reset ////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plDynamicEnvLayer::Reset()
|
||||
{
|
||||
GetDynamicEnvLayerDesc()->Reset(this, TRUE); // reset all pb2's
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
|
||||
|
||||
fIValid.SetEmpty();
|
||||
}
|
||||
|
||||
//// Update ///////////////////////////////////////////////////////////////////
|
||||
|
||||
void plDynamicEnvLayer::Update(TimeValue t, Interval& valid)
|
||||
{
|
||||
if (!fIValid.InInterval(t))
|
||||
{
|
||||
fIValid.SetInfinite();
|
||||
|
||||
fUVGen->Update(t,fIValid);
|
||||
fBitmapPB->GetValidity(t, fIValid);
|
||||
}
|
||||
|
||||
valid &= fIValid;
|
||||
}
|
||||
|
||||
//// Validity /////////////////////////////////////////////////////////////////
|
||||
|
||||
Interval plDynamicEnvLayer::Validity(TimeValue t)
|
||||
{
|
||||
//TODO: Update fIValid here
|
||||
|
||||
// mf horse - Hacking this in just to get animations working.
|
||||
// No warranty on this not being stupid.
|
||||
Interval v = FOREVER;
|
||||
fBitmapPB->GetValidity(t, v);
|
||||
v &= fUVGen->Validity(t);
|
||||
return v;
|
||||
}
|
||||
|
||||
//// CreateParamDlg ///////////////////////////////////////////////////////////
|
||||
|
||||
ParamDlg* plDynamicEnvLayer::CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp)
|
||||
{
|
||||
fIMtlParams = imp;
|
||||
IAutoMParamDlg* masterDlg = plDynamicEnvLayerDesc.CreateParamDlgs(hwMtlEdit, imp, this);
|
||||
|
||||
return masterDlg;
|
||||
}
|
||||
|
||||
//// SetDlgThing //////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL plDynamicEnvLayer::SetDlgThing(ParamDlg* dlg)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//// Reference Functions //////////////////////////////////////////////////////
|
||||
|
||||
int plDynamicEnvLayer::NumRefs()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
RefTargetHandle plDynamicEnvLayer::GetReference( int i )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
case kRefUVGen: return fUVGen;
|
||||
case kRefBitmap: return fBitmapPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void plDynamicEnvLayer::SetReference( int i, RefTargetHandle rtarg )
|
||||
{
|
||||
Interval garbage;
|
||||
|
||||
switch( i )
|
||||
{
|
||||
case kRefUVGen:
|
||||
fUVGen = (UVGen *)rtarg;
|
||||
if( fUVGen )
|
||||
fUVGen->Update( TimeValue( 0 ), garbage );
|
||||
break;
|
||||
case kRefBitmap:
|
||||
fBitmapPB = (IParamBlock2 *)rtarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//// ParamBlock Functions /////////////////////////////////////////////////////
|
||||
|
||||
int plDynamicEnvLayer::NumParamBlocks()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
IParamBlock2 *plDynamicEnvLayer::GetParamBlock( int i )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
case 0: return fBitmapPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IParamBlock2 *plDynamicEnvLayer::GetParamBlockByID( BlockID id )
|
||||
{
|
||||
if( fBitmapPB->ID() == id )
|
||||
return fBitmapPB;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//// Clone ////////////////////////////////////////////////////////////////////
|
||||
|
||||
RefTargetHandle plDynamicEnvLayer::Clone( RemapDir &remap )
|
||||
{
|
||||
plDynamicEnvLayer *mnew = TRACKED_NEW plDynamicEnvLayer();
|
||||
*((MtlBase*)mnew) = *((MtlBase*)this); // copy superclass stuff
|
||||
mnew->ReplaceReference(kRefBitmap, remap.CloneRef(fBitmapPB));
|
||||
mnew->ReplaceReference(kRefUVGen, remap.CloneRef(fUVGen));
|
||||
BaseClone(this, mnew, remap);
|
||||
return (RefTargetHandle)mnew;
|
||||
}
|
||||
|
||||
//// SubAnim Functions ////////////////////////////////////////////////////////
|
||||
|
||||
int plDynamicEnvLayer::NumSubs()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Animatable *plDynamicEnvLayer::SubAnim( int i )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
case kRefBitmap: return fBitmapPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TSTR plDynamicEnvLayer::SubAnimName( int i )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
case kRefBitmap: return fBitmapPB->GetLocalName();
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
//// NotifyRefChanged /////////////////////////////////////////////////////////
|
||||
|
||||
RefResult plDynamicEnvLayer::NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message )
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case REFMSG_CHANGE:
|
||||
{
|
||||
fIValid.SetEmpty();
|
||||
|
||||
if (hTarget == fBitmapPB)
|
||||
{
|
||||
// see if this message came from a changing parameter in the pblock,
|
||||
// if so, limit rollout update to the changing item and update any active viewport texture
|
||||
ParamID changingParam = fBitmapPB->LastNotifyParamID();
|
||||
fBitmapPB->GetDesc()->InvalidateUI(changingParam);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case REFMSG_UV_SYM_CHANGE:
|
||||
IDiscardTexHandle();
|
||||
break;
|
||||
}
|
||||
|
||||
return REF_SUCCEED;
|
||||
}
|
||||
|
||||
//// Save/Load ////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TEX_HDR_CHUNK 0x5000
|
||||
|
||||
IOResult plDynamicEnvLayer::Save(ISave *isave)
|
||||
{
|
||||
IOResult res;
|
||||
|
||||
isave->BeginChunk(TEX_HDR_CHUNK);
|
||||
res = MtlBase::Save(isave);
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
isave->EndChunk();
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult plDynamicEnvLayer::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
if (iload->CurChunkID() == TEX_HDR_CHUNK)
|
||||
{
|
||||
res = MtlBase::Load(iload);
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
//// EvalColor ////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Point2 CompUV(float x, float y, float z)
|
||||
{
|
||||
return Point2( 0.5f * ( x / z + 1.0f ), 0.5f * ( y / z + 1.0f ) );
|
||||
}
|
||||
|
||||
AColor plDynamicEnvLayer::EvalColor(ShadeContext& sc)
|
||||
{
|
||||
if (!sc.doMaps)
|
||||
return AColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
AColor color;
|
||||
if (sc.GetCache(this, color))
|
||||
return color;
|
||||
|
||||
if (gbufID)
|
||||
sc.SetGBufferID(gbufID);
|
||||
|
||||
color.White();
|
||||
|
||||
sc.PutCache(this, color);
|
||||
return color;
|
||||
}
|
||||
|
||||
float plDynamicEnvLayer::EvalMono(ShadeContext& sc)
|
||||
{
|
||||
return Intens(EvalColor(sc));
|
||||
}
|
||||
|
||||
Point3 plDynamicEnvLayer::EvalNormalPerturb(ShadeContext& sc)
|
||||
{
|
||||
// Return the perturbation to apply to a normal for bump mapping
|
||||
return Point3(0, 0, 0);
|
||||
}
|
||||
|
||||
ULONG plDynamicEnvLayer::LocalRequirements(int subMtlNum)
|
||||
{
|
||||
return MTLREQ_VIEW_DEP;
|
||||
}
|
||||
|
||||
void plDynamicEnvLayer::IDiscardTexHandle()
|
||||
{
|
||||
if (fTexHandle)
|
||||
{
|
||||
fTexHandle->DeleteThis();
|
||||
fTexHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void plDynamicEnvLayer::ActivateTexDisplay(BOOL onoff)
|
||||
{
|
||||
if (!onoff)
|
||||
IDiscardTexHandle();
|
||||
}
|
||||
|
||||
BITMAPINFO *plDynamicEnvLayer::GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono, BOOL forceW, BOOL forceH)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD plDynamicEnvLayer::GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker)
|
||||
{
|
||||
// FIXME: ignore validity for now
|
||||
if (fTexHandle && fIValid.InInterval(t))// && texTime == CalcFrame(t))
|
||||
return fTexHandle->GetHandle();
|
||||
else
|
||||
{
|
||||
IDiscardTexHandle();
|
||||
|
||||
fTexTime = 0;//CalcFrame(t);
|
||||
fTexHandle = thmaker.MakeHandle(GetVPDisplayDIB(t, thmaker, fIValid));
|
||||
if (fTexHandle)
|
||||
return fTexHandle->GetHandle();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//// MustBeUnique /////////////////////////////////////////////////////////////
|
||||
// Fun stuff here. If our anchor is set to nil (i.e. "self"), then we must be
|
||||
// unique for each object we're applied to. However, that means the material
|
||||
// must *ALSO* be unique. Hence why this function is called by
|
||||
// hsMaterialConverter::IMustBeUniqueMaterial().
|
||||
|
||||
bool plDynamicEnvLayer::MustBeUnique( void )
|
||||
{
|
||||
if( fBitmapPB->GetINode( kBmpAnchorNode ) == nil )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -0,0 +1,168 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plDynamicEnvLayer - Dynamic EnvironmentMap MAX Layer //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 8.22.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plDynamicEnvLayer_h
|
||||
#define _plDynamicEnvLayer_h
|
||||
|
||||
#include "Max.h"
|
||||
#include "plPlasmaMAXLayer.h"
|
||||
|
||||
class ClassDesc2;
|
||||
class IParamBlock2;
|
||||
|
||||
//// Class Definition /////////////////////////////////////////////////////////
|
||||
|
||||
class plDynamicEnvLayer : public plPlasmaMAXLayer
|
||||
{
|
||||
protected:
|
||||
// Parameter block
|
||||
IParamBlock2 *fBitmapPB;
|
||||
UVGen *fUVGen;
|
||||
|
||||
IMtlParams *fIMtlParams;
|
||||
|
||||
TexHandle *fTexHandle;
|
||||
TimeValue fTexTime;
|
||||
|
||||
Interval fIValid;
|
||||
|
||||
friend class DELBitmapDlgProc;
|
||||
|
||||
public:
|
||||
// Ref nums
|
||||
enum
|
||||
{
|
||||
kRefUVGen,
|
||||
kRefBitmap,
|
||||
};
|
||||
|
||||
// Block ID's
|
||||
enum
|
||||
{
|
||||
kBlkBitmap,
|
||||
};
|
||||
|
||||
plDynamicEnvLayer();
|
||||
~plDynamicEnvLayer();
|
||||
void DeleteThis() { delete this; }
|
||||
|
||||
//From MtlBase
|
||||
ParamDlg *CreateParamDlg( HWND hwMtlEdit, IMtlParams *imp );
|
||||
BOOL SetDlgThing( ParamDlg* dlg );
|
||||
void Update( TimeValue t, Interval& valid );
|
||||
void Reset();
|
||||
Interval Validity( TimeValue t );
|
||||
ULONG LocalRequirements( int subMtlNum );
|
||||
|
||||
//From Texmap
|
||||
RGBA EvalColor( ShadeContext& sc );
|
||||
float EvalMono( ShadeContext& sc );
|
||||
Point3 EvalNormalPerturb( ShadeContext& sc );
|
||||
|
||||
// For displaying textures in the viewport
|
||||
BOOL SupportTexDisplay() { return TRUE; }
|
||||
void ActivateTexDisplay(BOOL onoff);
|
||||
BITMAPINFO *GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono=FALSE, int forceW=0, int forceH=0);
|
||||
DWORD GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
|
||||
|
||||
virtual bool MustBeUnique( void );
|
||||
|
||||
protected:
|
||||
void IDiscardTexHandle();
|
||||
|
||||
public:
|
||||
void GetUVTransform(Matrix3 &uvtrans) { fUVGen->GetUVTransform(uvtrans); }
|
||||
int GetTextureTiling() { return fUVGen->GetTextureTiling(); }
|
||||
int GetUVWSource() { return fUVGen->GetUVWSource(); }
|
||||
virtual int GetMapChannel() { return fUVGen->GetMapChannel(); } // only relevant if above returns UVWSRC_EXPLICIT
|
||||
UVGen *GetTheUVGen() { return fUVGen; }
|
||||
|
||||
//TODO: Return anim index to reference index
|
||||
int SubNumToRefNum( int subNum ) { return kRefBitmap; /* Only one sub*/ }
|
||||
|
||||
// Loading/Saving
|
||||
IOResult Load(ILoad *iload);
|
||||
IOResult Save(ISave *isave);
|
||||
|
||||
//From Animatable
|
||||
Class_ID ClassID() { return DYNAMIC_ENV_LAYER_CLASS_ID; }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
void GetClassName( TSTR& s );
|
||||
|
||||
RefTargetHandle Clone( RemapDir &remap );
|
||||
RefResult NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message );
|
||||
|
||||
int NumSubs();
|
||||
Animatable *SubAnim(int i);
|
||||
TSTR SubAnimName(int i);
|
||||
|
||||
int NumRefs();
|
||||
RefTargetHandle GetReference( int i );
|
||||
void SetReference( int i, RefTargetHandle rtarg );
|
||||
|
||||
int NumParamBlocks(); // return number of ParamBlocks in this instance
|
||||
IParamBlock2 *GetParamBlock(int i); // return i'th ParamBlock
|
||||
IParamBlock2 *GetParamBlockByID(BlockID id); // return id'd ParamBlock
|
||||
|
||||
/// ParamBlock accessors
|
||||
enum
|
||||
{
|
||||
kScalingAny,
|
||||
kScalingHalf,
|
||||
kScalingNone
|
||||
};
|
||||
|
||||
// Param ID's
|
||||
enum
|
||||
{
|
||||
// General params
|
||||
kBmpTextureSize,
|
||||
kBmpAnchorNode,
|
||||
kBmpLastTextureSize, // Annoying, but necessary to clamp texture sizes to powers of 2
|
||||
kBmpRefract
|
||||
};
|
||||
|
||||
// Pure virtual accessors for the various bitmap related elements
|
||||
virtual Bitmap *GetMaxBitmap(int index = 0) { hsAssert( false, "Function call not valid on this type of layer." ); return nil; }
|
||||
virtual PBBitmap *GetPBBitmap( int index = 0 ) { hsAssert( false, "Function call not valid on this type of layer." ); return nil; }
|
||||
virtual int GetNumBitmaps( void ) { return 0; }
|
||||
|
||||
protected:
|
||||
virtual void ISetMaxBitmap(Bitmap *bitmap, int index = 0) { hsAssert( false, "Function call not valid on this type of layer." ); }
|
||||
virtual void ISetPBBitmap( PBBitmap *pbbm, int index = 0 ){ hsAssert( false, "Function call not valid on this type of layer." ); }
|
||||
};
|
||||
|
||||
#endif // _plDynamicEnvLayer_h
|
@ -0,0 +1,250 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plDynamicEnvLayer ParamBlock Functions //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 8.22.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// PickAnchorNode ///////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class PickAnchorNode : public PickObjectProc
|
||||
{
|
||||
public:
|
||||
plDynamicEnvLayer *fLayer;
|
||||
HWND fHWnd;
|
||||
int bleah;
|
||||
|
||||
PickAnchorNode() { fLayer = NULL; }
|
||||
|
||||
BOOL Pick( INode *node )
|
||||
{
|
||||
const char *dbgNodeName = node->GetName();
|
||||
|
||||
if( fLayer )
|
||||
fLayer->GetParamBlockByID( plDynamicEnvLayer::kBlkBitmap )->SetValue( plDynamicEnvLayer::kBmpAnchorNode, TimeValue( 0 ), node );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void EnterMode() { ISetButton( TRUE ); }
|
||||
void ExitMode() { ISetButton( FALSE ); }
|
||||
|
||||
BOOL Filter( INode *node )
|
||||
{
|
||||
Object *obj = node->EvalWorldState( 0 ).obj;
|
||||
if( obj != NULL )
|
||||
{
|
||||
if( obj->CanConvertToType( triObjectClassID ) ||
|
||||
obj->ClassID() == Class_ID( DUMMY_CLASS_ID, 0 ) )
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void ISetButton( BOOL checkIt )
|
||||
{
|
||||
ICustButton *iBut = GetICustButton( GetDlgItem( fHWnd, IDC_ANCHOR_NODE ) );
|
||||
if( iBut )
|
||||
{
|
||||
iBut->SetCheck( checkIt );
|
||||
if( fLayer )
|
||||
{
|
||||
if( fLayer->GetParamBlockByID( plDynamicEnvLayer::kBlkBitmap )->GetINode( plDynamicEnvLayer::kBmpAnchorNode ) == NULL )
|
||||
iBut->SetText( _T( "<self>" ) );
|
||||
}
|
||||
}
|
||||
ReleaseICustButton( iBut );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// ParamBlock Dialog Proc ///////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DELBitmapDlgProc : public ParamMap2UserDlgProc
|
||||
{
|
||||
PickAnchorNode fPickAnchorCallback;
|
||||
|
||||
/// Called to update the controls of the dialog
|
||||
virtual void Update( TimeValue t, Interval &valid, IParamMap2 *map )
|
||||
{
|
||||
IParamBlock2 *pblock;
|
||||
int i;
|
||||
|
||||
|
||||
ParamMap2UserDlgProc::Update( t, valid, map );
|
||||
|
||||
pblock = map->GetParamBlock();
|
||||
|
||||
i = pblock->GetInt( plDynamicEnvLayer::kBmpTextureSize, t );
|
||||
pblock->SetValue( plDynamicEnvLayer::kBmpLastTextureSize, t, i );
|
||||
|
||||
if( pblock->GetINode( plDynamicEnvLayer::kBmpAnchorNode ) == NULL )
|
||||
{
|
||||
ICustButton *bmSelectBtn = GetICustButton( GetDlgItem( pblock->GetMap()->GetHWnd(), IDC_ANCHOR_NODE ) );
|
||||
bmSelectBtn->SetText( _T( "<self>" ) );
|
||||
ReleaseICustButton( bmSelectBtn );
|
||||
}
|
||||
}
|
||||
|
||||
/// Clamp texture sizes to a power of 2
|
||||
void IClampTexSizeSpinner( TimeValue t, IParamMap2 *map )
|
||||
{
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
|
||||
int lastVal = pblock->GetInt( plDynamicEnvLayer::kBmpLastTextureSize, t );
|
||||
int tempVal, newVal = pblock->GetInt( plDynamicEnvLayer::kBmpTextureSize, t );
|
||||
|
||||
if( newVal < lastVal )
|
||||
{
|
||||
lastVal = newVal;
|
||||
for( tempVal = 1; tempVal < newVal; tempVal <<= 1 );
|
||||
newVal = tempVal >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastVal = newVal;
|
||||
for( tempVal = 1; tempVal < newVal; tempVal <<= 1 );
|
||||
newVal = tempVal;
|
||||
}
|
||||
|
||||
pblock->SetValue( plDynamicEnvLayer::kBmpTextureSize, t, newVal );
|
||||
pblock->SetValue( plDynamicEnvLayer::kBmpLastTextureSize, t, newVal );
|
||||
}
|
||||
|
||||
/// Main message proc
|
||||
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
break;
|
||||
|
||||
case CC_SPINNER_CHANGE:
|
||||
if( LOWORD( wParam ) == IDC_TEXSIZE_SPIN )
|
||||
IClampTexSizeSpinner( t, map );
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
|
||||
if( HIWORD( wParam ) == EN_CHANGE && LOWORD( wParam ) == IDC_TEXSIZE_EDIT )
|
||||
IClampTexSizeSpinner( t, map );
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_ANCHOR_NODE )
|
||||
{
|
||||
plDynamicEnvLayer *layer = (plDynamicEnvLayer *)map->GetParamBlock()->GetOwner();
|
||||
|
||||
layer->fIMtlParams->EndPickMode();
|
||||
fPickAnchorCallback.fHWnd = hWnd;
|
||||
fPickAnchorCallback.fLayer = layer;
|
||||
|
||||
layer->fIMtlParams->SetPickMode( &fPickAnchorCallback );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void DeleteThis() {};
|
||||
};
|
||||
|
||||
static DELBitmapDlgProc gDELBitmapDlgProc;
|
||||
|
||||
class BleahPBAccessor : public PBAccessor
|
||||
{
|
||||
public:
|
||||
void Set(PB2Value& val, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t)
|
||||
{
|
||||
plDynamicEnvLayer* layer = (plDynamicEnvLayer *)owner;
|
||||
IParamBlock2 *pb = layer->GetParamBlockByID( plDynamicEnvLayer::kBlkBitmap );
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case plDynamicEnvLayer::kBmpAnchorNode:
|
||||
INode *newNode = (INode *)val.r;
|
||||
if( newNode == NULL )
|
||||
{
|
||||
// Instead of displaying "none", display "<self>", since that's what nil means
|
||||
// for us
|
||||
ICustButton *bmSelectBtn = GetICustButton( GetDlgItem( pb->GetMap()->GetHWnd(), IDC_ANCHOR_NODE ) );
|
||||
bmSelectBtn->SetText( _T( "<self>" ) );
|
||||
ReleaseICustButton( bmSelectBtn );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval &valid)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static BleahPBAccessor gBleahPBAccessor;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// ParamBlock Definition ////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static ParamBlockDesc2 gBitmapParamBlk
|
||||
(
|
||||
plDynamicEnvLayer::kBlkBitmap, _T("bitmap"), 0, GetDynamicEnvLayerDesc(),
|
||||
P_AUTO_CONSTRUCT + P_AUTO_UI, plDynamicEnvLayer::kRefBitmap,
|
||||
|
||||
IDD_DYNAMIC_ENVMAP_LAYER, IDS_DYNAMIC_ENVMAP_LAYER_TEX, 0, 0, &gDELBitmapDlgProc,
|
||||
|
||||
// General parameters
|
||||
plDynamicEnvLayer::kBmpTextureSize, _T("textureSize"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_TEXSIZE_EDIT, IDC_TEXSIZE_SPIN, SPIN_AUTOSCALE,
|
||||
p_range, 4, 512,
|
||||
p_default, 64,
|
||||
end,
|
||||
plDynamicEnvLayer::kBmpAnchorNode, _T("anchorNode"), TYPE_INODE, 0, 0,
|
||||
p_ui, TYPE_PICKNODEBUTTON, IDC_ANCHOR_NODE,
|
||||
p_prompt, IDS_SELECT_ANCHOR,
|
||||
p_accessor, &gBleahPBAccessor,
|
||||
end,
|
||||
plDynamicEnvLayer::kBmpLastTextureSize, _T("lastTextureSize"), TYPE_INT, 0, 0,
|
||||
end,
|
||||
|
||||
plDynamicEnvLayer::kBmpRefract, _T("refract"),TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_REFRACT,
|
||||
end,
|
||||
|
||||
end
|
||||
);
|
||||
|
@ -0,0 +1,559 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plDynamicTextLayer.h"
|
||||
|
||||
#include "iparamb2.h"
|
||||
#include "iparamm2.h"
|
||||
#include "stdmat.h"
|
||||
|
||||
#include "plBMSampler.h"
|
||||
#include "../MaxMain/plPlasmaRefMsgs.h"
|
||||
|
||||
class plDynamicTextLayerClassDesc : public ClassDesc2
|
||||
{
|
||||
public:
|
||||
int IsPublic() { return TRUE; }
|
||||
void* Create(BOOL loading = FALSE) { return TRACKED_NEW plDynamicTextLayer(); }
|
||||
const TCHAR* ClassName() { return GetString(IDS_DYN_TEXT_LAYER); }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
Class_ID ClassID() { return DYN_TEXT_LAYER_CLASS_ID; }
|
||||
const TCHAR* Category() { return TEXMAP_CAT_2D; }
|
||||
const TCHAR* InternalName() { return _T("PlasmaDynamicTextLayer"); }
|
||||
HINSTANCE HInstance() { return hInstance; }
|
||||
};
|
||||
static plDynamicTextLayerClassDesc plDynamicTextLayerDesc;
|
||||
ClassDesc2* GetDynamicTextLayerDesc() { return &plDynamicTextLayerDesc; }
|
||||
|
||||
#include "plDynamicTextLayerBitmapPB.cpp"
|
||||
|
||||
ParamDlg* plDynamicTextLayer::fUVGenDlg = NULL;
|
||||
|
||||
plDynamicTextLayer::plDynamicTextLayer() :
|
||||
fBitmapPB(NULL),
|
||||
fUVGen(NULL),
|
||||
fTexHandle(NULL),
|
||||
fTexTime(0),
|
||||
fIValid(NEVER)
|
||||
{
|
||||
fInitBitmap = NULL;
|
||||
|
||||
plDynamicTextLayerDesc.MakeAutoParamBlocks(this);
|
||||
ReplaceReference(kRefUVGen, GetNewDefaultUVGen());
|
||||
}
|
||||
|
||||
plDynamicTextLayer::~plDynamicTextLayer()
|
||||
{
|
||||
if( fInitBitmap )
|
||||
fInitBitmap->DeleteThis();
|
||||
|
||||
IDiscardTexHandle();
|
||||
}
|
||||
|
||||
//From MtlBase
|
||||
void plDynamicTextLayer::Reset()
|
||||
{
|
||||
GetDynamicTextLayerDesc()->Reset(this, TRUE); // reset all pb2's
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
|
||||
|
||||
fIValid.SetEmpty();
|
||||
}
|
||||
|
||||
void plDynamicTextLayer::Update(TimeValue t, Interval& valid)
|
||||
{
|
||||
if (!fIValid.InInterval(t))
|
||||
{
|
||||
fIValid.SetInfinite();
|
||||
|
||||
fUVGen->Update(t,fIValid);
|
||||
fBitmapPB->GetValidity(t, fIValid);
|
||||
}
|
||||
|
||||
// Gonna need to do this when we support animated bm's
|
||||
#if 0
|
||||
if (fBM)
|
||||
{
|
||||
if (bi.FirstFrame()!=bi.LastFrame())
|
||||
ivalid.SetInstant(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
valid &= fIValid;
|
||||
}
|
||||
|
||||
Interval plDynamicTextLayer::Validity(TimeValue t)
|
||||
{
|
||||
//TODO: Update fIValid here
|
||||
|
||||
// mf horse - Hacking this in just to get animations working.
|
||||
// No warranty on this not being stupid.
|
||||
Interval v = FOREVER;
|
||||
fBitmapPB->GetValidity(t, v);
|
||||
v &= fUVGen->Validity(t);
|
||||
return v;
|
||||
}
|
||||
|
||||
ParamDlg* plDynamicTextLayer::CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp)
|
||||
{
|
||||
fIMtlParams = imp;
|
||||
IAutoMParamDlg* masterDlg = plDynamicTextLayerDesc.CreateParamDlgs(hwMtlEdit, imp, this);
|
||||
|
||||
fUVGenDlg = fUVGen->CreateParamDlg(hwMtlEdit, imp);
|
||||
masterDlg->AddDlg(fUVGenDlg);
|
||||
|
||||
return masterDlg;
|
||||
}
|
||||
|
||||
BOOL plDynamicTextLayer::SetDlgThing(ParamDlg* dlg)
|
||||
{
|
||||
if (dlg == fUVGenDlg)
|
||||
{
|
||||
fUVGenDlg->SetThing(fUVGen);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int plDynamicTextLayer::NumRefs()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
//From ReferenceMaker
|
||||
RefTargetHandle plDynamicTextLayer::GetReference(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen: return fUVGen;
|
||||
case kRefBitmap: return fBitmapPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void plDynamicTextLayer::SetReference(int i, RefTargetHandle rtarg)
|
||||
{
|
||||
Interval garbage;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen:
|
||||
fUVGen = (UVGen *)rtarg;
|
||||
if( fUVGen )
|
||||
fUVGen->Update( TimeValue( 0 ), garbage );
|
||||
break;
|
||||
case kRefBitmap:
|
||||
fBitmapPB = (IParamBlock2 *)rtarg;
|
||||
// KLUDGE: If the paramblock is being set chances are we are being created or
|
||||
// loaded. In the case of load, we want to refresh our textures.
|
||||
if (fBitmapPB)
|
||||
RefreshBitmaps();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int plDynamicTextLayer::NumParamBlocks()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
IParamBlock2* plDynamicTextLayer::GetParamBlock(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: return fBitmapPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IParamBlock2* plDynamicTextLayer::GetParamBlockByID(BlockID id)
|
||||
{
|
||||
if (fBitmapPB->ID() == id)
|
||||
return fBitmapPB;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//From ReferenceTarget
|
||||
RefTargetHandle plDynamicTextLayer::Clone(RemapDir &remap)
|
||||
{
|
||||
plDynamicTextLayer *mnew = TRACKED_NEW plDynamicTextLayer();
|
||||
*((MtlBase*)mnew) = *((MtlBase*)this); // copy superclass stuff
|
||||
mnew->ReplaceReference(kRefBitmap, remap.CloneRef(fBitmapPB));
|
||||
mnew->ReplaceReference(kRefUVGen, remap.CloneRef(fUVGen));
|
||||
BaseClone(this, mnew, remap);
|
||||
return (RefTargetHandle)mnew;
|
||||
}
|
||||
|
||||
int plDynamicTextLayer::NumSubs()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
Animatable* plDynamicTextLayer::SubAnim(int i)
|
||||
{
|
||||
//TODO: Return 'i-th' sub-anim
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen: return fUVGen;
|
||||
case kRefBitmap: return fBitmapPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TSTR plDynamicTextLayer::SubAnimName(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen: return "UVGen";
|
||||
case kRefBitmap: return fBitmapPB->GetLocalName();
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
RefResult plDynamicTextLayer::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case REFMSG_CHANGE:
|
||||
{
|
||||
fIValid.SetEmpty();
|
||||
|
||||
if (hTarget == fBitmapPB)
|
||||
{
|
||||
// see if this message came from a changing parameter in the pblock,
|
||||
// if so, limit rollout update to the changing item and update any active viewport texture
|
||||
ParamID changingParam = fBitmapPB->LastNotifyParamID();
|
||||
fBitmapPB->GetDesc()->InvalidateUI(changingParam);
|
||||
|
||||
if (changingParam != -1)
|
||||
IChanged();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case REFMSG_UV_SYM_CHANGE:
|
||||
IDiscardTexHandle();
|
||||
break;
|
||||
}
|
||||
|
||||
return REF_SUCCEED;
|
||||
}
|
||||
|
||||
void plDynamicTextLayer::IChanged()
|
||||
{
|
||||
IDiscardTexHandle();
|
||||
// Texture wasn't getting updated in the viewports, and this fixes it.
|
||||
// Don't know if it's the right way though.
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
|
||||
|
||||
// And this is so the SceneWatcher gets notified that the material on some of it's
|
||||
// referenced objects changed.
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_USER_MAT);
|
||||
}
|
||||
|
||||
#define TEX_HDR_CHUNK 0x5000
|
||||
|
||||
IOResult plDynamicTextLayer::Save(ISave *isave)
|
||||
{
|
||||
IOResult res;
|
||||
|
||||
isave->BeginChunk(TEX_HDR_CHUNK);
|
||||
res = MtlBase::Save(isave);
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
isave->EndChunk();
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult plDynamicTextLayer::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
if (iload->CurChunkID() == TEX_HDR_CHUNK)
|
||||
{
|
||||
res = MtlBase::Load(iload);
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
inline Point2 CompUV(float x, float y, float z)
|
||||
{
|
||||
return Point2( 0.5f * ( x / z + 1.0f ), 0.5f * ( y / z + 1.0f ) );
|
||||
}
|
||||
|
||||
Bitmap *plDynamicTextLayer::GetBitmap( TimeValue t )
|
||||
{
|
||||
return fInitBitmap;
|
||||
}
|
||||
|
||||
AColor plDynamicTextLayer::EvalColor(ShadeContext& sc)
|
||||
{
|
||||
if (!sc.doMaps)
|
||||
return AColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
AColor color;
|
||||
if (sc.GetCache(this, color))
|
||||
return color;
|
||||
|
||||
if (gbufID)
|
||||
sc.SetGBufferID(gbufID);
|
||||
|
||||
// Evaluate the Bitmap
|
||||
if( fBitmapPB->GetInt( kBmpUseInitImage ) && fInitBitmap )
|
||||
{
|
||||
plBMSampler mysamp( this, fInitBitmap );
|
||||
color = fUVGen->EvalUVMap( sc, &mysamp, TRUE );
|
||||
}
|
||||
else
|
||||
color.White();
|
||||
|
||||
// Invert color if specified
|
||||
if( fBitmapPB->GetInt( kBmpInvertColor ) )
|
||||
{
|
||||
color.r = 1.0f - color.r;
|
||||
color.g = 1.0f - color.g;
|
||||
color.b = 1.0f - color.b;
|
||||
}
|
||||
// Discard color if specified
|
||||
if( fBitmapPB->GetInt( kBmpDiscardColor ) )
|
||||
color.r = color.g = color.b = 1.0f;
|
||||
|
||||
// Invert alpha if specified
|
||||
if( fBitmapPB->GetInt( kBmpInvertAlpha ) )
|
||||
color.a = 1.0f - color.a;
|
||||
// Discard alpha if specified
|
||||
if( fBitmapPB->GetInt( kBmpDiscardAlpha ) )
|
||||
color.a = 1.0f;
|
||||
|
||||
sc.PutCache(this, color);
|
||||
return color;
|
||||
}
|
||||
|
||||
float plDynamicTextLayer::EvalMono(ShadeContext& sc)
|
||||
{
|
||||
return Intens(EvalColor(sc));
|
||||
}
|
||||
|
||||
Point3 plDynamicTextLayer::EvalNormalPerturb(ShadeContext& sc)
|
||||
{
|
||||
// Return the perturbation to apply to a normal for bump mapping
|
||||
return Point3(0, 0, 0);
|
||||
}
|
||||
|
||||
ULONG plDynamicTextLayer::LocalRequirements(int subMtlNum)
|
||||
{
|
||||
return fUVGen->Requirements( subMtlNum );
|
||||
}
|
||||
|
||||
void plDynamicTextLayer::IDiscardTexHandle()
|
||||
{
|
||||
if (fTexHandle)
|
||||
{
|
||||
fTexHandle->DeleteThis();
|
||||
fTexHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void plDynamicTextLayer::ActivateTexDisplay(BOOL onoff)
|
||||
{
|
||||
if (!onoff)
|
||||
IDiscardTexHandle();
|
||||
}
|
||||
|
||||
BITMAPINFO *plDynamicTextLayer::GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono, BOOL forceW, BOOL forceH)
|
||||
{
|
||||
// FIXME
|
||||
fTexTime = 0;//CalcFrame(t);
|
||||
// texValid = clipValid;
|
||||
BITMAPINFO *bmi = NULL;
|
||||
int xflags = 0;
|
||||
|
||||
// Create a bitmap to write into via Windows
|
||||
BITMAPINFO tempBMI;
|
||||
memset( &tempBMI.bmiHeader, 0, sizeof( BITMAPINFOHEADER ) );
|
||||
tempBMI.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
|
||||
tempBMI.bmiHeader.biWidth = fBitmapPB->GetInt( kBmpExportWidth );
|
||||
tempBMI.bmiHeader.biHeight = -(int)fBitmapPB->GetInt( kBmpExportHeight );
|
||||
tempBMI.bmiHeader.biPlanes = 1;
|
||||
tempBMI.bmiHeader.biCompression = BI_RGB;
|
||||
tempBMI.bmiHeader.biBitCount = 32;
|
||||
|
||||
DWORD *bitmapBits;
|
||||
HDC winDC = CreateCompatibleDC( nil );
|
||||
HBITMAP bitmap = CreateDIBSection( winDC, &tempBMI, DIB_RGB_COLORS, (void **)&bitmapBits, nil, 0 );
|
||||
|
||||
HBITMAP old = (HBITMAP)SelectObject( winDC, bitmap );
|
||||
|
||||
// Write into it now
|
||||
RECT r;
|
||||
SetRect( &r, 0, 0, fBitmapPB->GetInt( kBmpExportWidth ) - 1, fBitmapPB->GetInt( kBmpExportHeight ) - 1 );
|
||||
HBRUSH brush = CreateSolidBrush( RGB( 255, 0, 0 ) );
|
||||
FrameRect( winDC, &r, brush );
|
||||
DeleteObject( brush );
|
||||
|
||||
SetMapMode( winDC, MM_TEXT );
|
||||
SetBkMode( winDC, TRANSPARENT );
|
||||
SetTextAlign( winDC, TA_TOP | TA_LEFT );
|
||||
|
||||
// Background letters
|
||||
int nHeight = -MulDiv( 72, GetDeviceCaps( winDC, LOGPIXELSY ), 72 );
|
||||
HFONT winFont = CreateFont( nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, "Times New Roman" );
|
||||
if( winFont != nil )
|
||||
{
|
||||
HFONT origFont = (HFONT)SelectObject( winDC, winFont );
|
||||
SetTextColor( winDC, RGB( 32, 32, 32 ) );
|
||||
char str2[] = "ABCDEFG";
|
||||
::TextOut( winDC, 0, 0, str2, strlen( str2 ) );
|
||||
SelectObject( winDC, origFont );
|
||||
DeleteObject( winFont );
|
||||
}
|
||||
|
||||
nHeight = -MulDiv( 8, GetDeviceCaps( winDC, LOGPIXELSY ), 72 );
|
||||
winFont = CreateFont( nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, "Arial" );
|
||||
if( winFont != nil )
|
||||
{
|
||||
HFONT origFont = (HFONT)SelectObject( winDC, winFont );
|
||||
|
||||
SetTextColor( winDC, RGB( 255, 255, 255 ) );
|
||||
char str[] = "Dynamic Text";
|
||||
::TextOut( winDC, 0, 0, str, strlen( str ) );
|
||||
char str3[] = "This is 8 point Arial";
|
||||
::TextOut( winDC, 0, 12, str3, strlen( str3 ) );
|
||||
|
||||
SelectObject( winDC, origFont );
|
||||
DeleteObject( winFont );
|
||||
}
|
||||
|
||||
|
||||
/// Create a MAX bitmap and copy over the data, the painful way
|
||||
Bitmap *maxBmp;
|
||||
BitmapInfo maxInfo;
|
||||
|
||||
maxInfo.SetType( BMM_TRUE_32 );
|
||||
maxInfo.SetWidth( fBitmapPB->GetInt( kBmpExportWidth ) );
|
||||
maxInfo.SetHeight( fBitmapPB->GetInt( kBmpExportHeight ) );
|
||||
maxInfo.SetFlags( MAP_HAS_ALPHA );
|
||||
maxInfo.SetCustomFlag( 0 );
|
||||
maxBmp = TheManager->Create( &maxInfo );
|
||||
|
||||
PixelBuf l64( fBitmapPB->GetInt( kBmpExportWidth ) );
|
||||
for( int y = 0; y < fBitmapPB->GetInt( kBmpExportHeight ); y++ )
|
||||
{
|
||||
BMM_Color_64 *p64 = l64.Ptr();
|
||||
for( int x = 0; x < fBitmapPB->GetInt( kBmpExportWidth ); x++, p64++ )
|
||||
{
|
||||
COLORREF color = GetPixel( winDC, x, y );
|
||||
|
||||
if( color == RGB( 0, 0, 0 ) )
|
||||
{
|
||||
if( fBitmapPB->GetInt( kBmpUseInitImage ) && fInitBitmap != nil )
|
||||
fInitBitmap->GetLinearPixels( x, y, 1, p64 );
|
||||
else
|
||||
p64->r = p64->g = p64->b = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
p64->r = GetRValue( color ) << 8;
|
||||
p64->g = GetGValue( color ) << 8;
|
||||
p64->b = GetBValue( color ) << 8;
|
||||
}
|
||||
p64->a = 0xffff;
|
||||
}
|
||||
maxBmp->PutPixels( 0, y, fBitmapPB->GetInt( kBmpExportWidth ), l64.Ptr() );
|
||||
}
|
||||
|
||||
// Done with these now
|
||||
SelectObject( winDC, old );
|
||||
DeleteObject( bitmap );
|
||||
DeleteObject( winDC );
|
||||
|
||||
// Convert to a BITMAPINFO. Go figure.
|
||||
bmi = thmaker.BitmapToDIB( maxBmp, 0, xflags, forceW, forceH );
|
||||
|
||||
return bmi;
|
||||
}
|
||||
|
||||
DWORD plDynamicTextLayer::GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker)
|
||||
{
|
||||
// FIXME: ignore validity for now
|
||||
if (fTexHandle && fIValid.InInterval(t))// && texTime == CalcFrame(t))
|
||||
return fTexHandle->GetHandle();
|
||||
else
|
||||
{
|
||||
IDiscardTexHandle();
|
||||
|
||||
fTexTime = 0;//CalcFrame(t);
|
||||
fTexHandle = thmaker.MakeHandle(GetVPDisplayDIB(t, thmaker, fIValid));
|
||||
if (fTexHandle)
|
||||
return fTexHandle->GetHandle();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char *plDynamicTextLayer::GetTextureName( int which )
|
||||
{
|
||||
PBBitmap *pbbm = fBitmapPB->GetBitmap( kBmpInitBitmap );
|
||||
if( pbbm )
|
||||
return pbbm->bi.Name();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void plDynamicTextLayer::ISetPBBitmap(PBBitmap *pbbm, int index /* = 0 */)
|
||||
{
|
||||
fBitmapPB->SetValue( (ParamID)kBmpInitBitmap, 0, pbbm );
|
||||
}
|
||||
|
||||
PBBitmap *plDynamicTextLayer::GetPBBitmap(int index /* = 0 */)
|
||||
{
|
||||
return fBitmapPB->GetBitmap( (ParamID)kBmpInitBitmap );
|
||||
}
|
||||
|
||||
//// GetSamplerInfo ///////////////////////////////////////////////////////////
|
||||
// Virtual function called by plBMSampler to get various things while sampling
|
||||
// the layer's image
|
||||
|
||||
bool plDynamicTextLayer::GetSamplerInfo( plBMSamplerData *samplerData )
|
||||
{
|
||||
if( fBitmapPB->GetInt( (ParamID)kBmpDiscardAlpha ) )
|
||||
samplerData->fAlphaSource = plBMSamplerData::kDiscard;
|
||||
else
|
||||
samplerData->fAlphaSource = plBMSamplerData::kFromTexture;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -0,0 +1,212 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plDynamicTextLayer - Dynamic Run-time Text MAX Layer //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 1.13.2002 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plDynamicTextLayer_h
|
||||
#define _plDynamicTextLayer_h
|
||||
|
||||
#include "Max.h"
|
||||
#include "../resource.h"
|
||||
#include "plPlasmaMAXLayer.h"
|
||||
|
||||
class ClassDesc2;
|
||||
class IParamBlock2;
|
||||
class DTLPBAccessor;
|
||||
|
||||
ClassDesc2* GetDynamicTextLayerDesc();
|
||||
|
||||
extern TCHAR *GetString(int id);
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
|
||||
//// Class Definition /////////////////////////////////////////////////////////
|
||||
|
||||
class plDynamicTextLayer : public plPlasmaMAXLayer
|
||||
{
|
||||
protected:
|
||||
friend class DTLPBAccessor;
|
||||
|
||||
// Parameter block
|
||||
IParamBlock2 *fBitmapPB;
|
||||
UVGen *fUVGen;
|
||||
|
||||
IMtlParams *fIMtlParams;
|
||||
|
||||
TexHandle *fTexHandle;
|
||||
TimeValue fTexTime;
|
||||
|
||||
Interval fIValid;
|
||||
|
||||
Bitmap *fInitBitmap;
|
||||
|
||||
static ParamDlg *fUVGenDlg;
|
||||
|
||||
friend class DTLBitmapDlgProc;
|
||||
|
||||
|
||||
public:
|
||||
// Ref nums
|
||||
enum
|
||||
{
|
||||
kRefUVGen,
|
||||
kRefBitmap,
|
||||
};
|
||||
|
||||
// Block ID's
|
||||
enum
|
||||
{
|
||||
kBlkBitmap,
|
||||
};
|
||||
|
||||
plDynamicTextLayer();
|
||||
~plDynamicTextLayer();
|
||||
void DeleteThis() { delete this; }
|
||||
|
||||
//From MtlBase
|
||||
ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
|
||||
BOOL SetDlgThing(ParamDlg* dlg);
|
||||
void Update(TimeValue t, Interval& valid);
|
||||
void Reset();
|
||||
Interval Validity(TimeValue t);
|
||||
ULONG LocalRequirements(int subMtlNum);
|
||||
|
||||
//From Texmap
|
||||
RGBA EvalColor(ShadeContext& sc);
|
||||
float EvalMono(ShadeContext& sc);
|
||||
Point3 EvalNormalPerturb(ShadeContext& sc);
|
||||
|
||||
// For displaying textures in the viewport
|
||||
BOOL SupportTexDisplay() { return TRUE; }
|
||||
void ActivateTexDisplay(BOOL onoff);
|
||||
BITMAPINFO *GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono=FALSE, int forceW=0, int forceH=0);
|
||||
DWORD GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
|
||||
protected:
|
||||
void IChanged();
|
||||
void IDiscardTexHandle();
|
||||
|
||||
public:
|
||||
void GetUVTransform(Matrix3 &uvtrans) { fUVGen->GetUVTransform(uvtrans); }
|
||||
int GetTextureTiling() { return fUVGen->GetTextureTiling(); }
|
||||
int GetUVWSource() { return fUVGen->GetUVWSource(); }
|
||||
virtual int GetMapChannel () { return fUVGen->GetMapChannel(); } // only relevant if above returns UVWSRC_EXPLICIT
|
||||
UVGen *GetTheUVGen() { return fUVGen; }
|
||||
|
||||
//TODO: Return anim index to reference index
|
||||
int SubNumToRefNum(int subNum) { return subNum; }
|
||||
|
||||
|
||||
// Loading/Saving
|
||||
IOResult Load(ILoad *iload);
|
||||
IOResult Save(ISave *isave);
|
||||
|
||||
//From Animatable
|
||||
Class_ID ClassID() { return DYN_TEXT_LAYER_CLASS_ID; }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
void GetClassName(TSTR& s) { s = GetString(IDS_DYN_TEXT_LAYER); }
|
||||
|
||||
RefTargetHandle Clone( RemapDir &remap );
|
||||
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message);
|
||||
|
||||
int NumSubs();
|
||||
Animatable* SubAnim(int i);
|
||||
TSTR SubAnimName(int i);
|
||||
|
||||
// TODO: Maintain the number or references here
|
||||
int NumRefs();
|
||||
RefTargetHandle GetReference(int i);
|
||||
void SetReference(int i, RefTargetHandle rtarg);
|
||||
|
||||
int NumParamBlocks(); // return number of ParamBlocks in this instance
|
||||
IParamBlock2* GetParamBlock(int i); // return i'th ParamBlock
|
||||
IParamBlock2* GetParamBlockByID(BlockID id); // return id'd ParamBlock
|
||||
|
||||
const char *GetTextureName( int which );
|
||||
virtual Bitmap* GetBitmap(TimeValue t);
|
||||
|
||||
|
||||
/// ParamBlock accessors
|
||||
enum
|
||||
{
|
||||
kScalingAny,
|
||||
kScalingHalf,
|
||||
kScalingNone
|
||||
};
|
||||
|
||||
// Param ID's
|
||||
enum
|
||||
{
|
||||
kBmpExportWidth,
|
||||
kBmpExportHeight,
|
||||
kBmpExportLastWidth, // Annoying fields, these two, but they're necessary
|
||||
kBmpExportLastHeight, // for clamping the spinners to powers of 2
|
||||
|
||||
// Misc
|
||||
kBmpDiscardColor,
|
||||
kBmpInvertColor,
|
||||
kBmpDiscardAlpha,
|
||||
kBmpInvertAlpha,
|
||||
|
||||
// Static text settings
|
||||
kBmpMakeStatic,
|
||||
kBmpText,
|
||||
kBmpFontFace,
|
||||
kBmpFontSize,
|
||||
kBmpLeftMargin,
|
||||
kBmpTopMargin,
|
||||
kBmpRightMargin,
|
||||
kBmpBottomMargin,
|
||||
|
||||
// Initial image settings
|
||||
kBmpUseInitImage,
|
||||
kBmpInitBitmap,
|
||||
|
||||
kBmpIncludeAlphaChannel
|
||||
};
|
||||
|
||||
// Pure virtual accessors for the various bitmap related elements
|
||||
virtual Bitmap *GetMaxBitmap(int index = 0) { return fInitBitmap; }
|
||||
virtual PBBitmap *GetPBBitmap( int index = 0 );
|
||||
virtual int GetNumBitmaps( void ) { return 1; }
|
||||
|
||||
// Virtual function called by plBMSampler to get various things while sampling the layer's image
|
||||
virtual bool GetSamplerInfo( plBMSamplerData *samplerData );
|
||||
|
||||
protected:
|
||||
virtual void ISetMaxBitmap( Bitmap *bitmap, int index = 0 ) { fInitBitmap = bitmap; }
|
||||
virtual void ISetPBBitmap( PBBitmap *pbbm, int index = 0 );
|
||||
};
|
||||
|
||||
#endif // _plDynamicTextLayer_h
|
@ -0,0 +1,304 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plDynamicTextLayer.h"
|
||||
|
||||
#include "iparamb2.h"
|
||||
#include "iparamm2.h"
|
||||
#include "stdmat.h"
|
||||
|
||||
#include "plBMSampler.h"
|
||||
#include "../MaxMain/plPlasmaRefMsgs.h"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// ParamBlock Dialog Proc ///////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DTLBitmapDlgProc : public ParamMap2UserDlgProc
|
||||
{
|
||||
/// Called to update the controls of the dialog
|
||||
virtual void Update( TimeValue t, Interval &valid, IParamMap2 *map )
|
||||
{
|
||||
IParamBlock2 *pblock;
|
||||
BitmapInfo bi;
|
||||
ICustButton *bmSelectBtn;
|
||||
|
||||
|
||||
ParamMap2UserDlgProc::Update( t, valid, map );
|
||||
|
||||
pblock = map->GetParamBlock();
|
||||
|
||||
plDynamicTextLayer *layer = (plDynamicTextLayer *)map->GetParamBlock()->GetOwner();
|
||||
|
||||
bmSelectBtn = GetICustButton( GetDlgItem( map->GetHWnd(), IDC_INITIMAGE ) );
|
||||
PBBitmap *pbbm = pblock->GetBitmap( plDynamicTextLayer::kBmpInitBitmap );
|
||||
if( pbbm )
|
||||
bmSelectBtn->SetText( (TCHAR *)pbbm->bi.Filename() );
|
||||
else
|
||||
bmSelectBtn->SetText( _T( "None" ) );
|
||||
ReleaseICustButton( bmSelectBtn );
|
||||
}
|
||||
|
||||
/// Clamp texture sizes to a power of 2
|
||||
void IClampTexSizeSpinner( TimeValue t, IParamMap2 *map )
|
||||
{
|
||||
}
|
||||
|
||||
/// Main message proc
|
||||
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
break;
|
||||
|
||||
/// Note: the following *could* be done in the accessor, except that you end up in an
|
||||
/// infinite loop updating the values. Not good.
|
||||
case CC_SPINNER_CHANGE:
|
||||
|
||||
if( LOWORD( wParam ) == IDC_EXPORTWIDTH_SPINNER )
|
||||
IClampTexSizeSpinner( t, map, true );
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_EXPORTHEIGHT_SPINNER )
|
||||
IClampTexSizeSpinner( t, map, false );
|
||||
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
|
||||
if( HIWORD( wParam ) == EN_CHANGE && LOWORD( wParam ) == IDC_EXPORTWIDTH )
|
||||
IClampTexSizeSpinner( t, map, true );
|
||||
|
||||
else if( HIWORD( wParam ) == EN_CHANGE && LOWORD( wParam ) == IDC_EXPORTHEIGHT )
|
||||
IClampTexSizeSpinner( t, map, false );
|
||||
|
||||
else if( HIWORD( wParam ) == BN_CLICKED && LOWORD( wParam ) == IDC_INITIMAGE_RELOAD )
|
||||
{
|
||||
// TEMP
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
PBBitmap *pbbm = pblock->GetBitmap( plDynamicTextLayer::kBmpInitBitmap );
|
||||
if( pbbm )
|
||||
{
|
||||
plDynamicTextLayer *layer = (plDynamicTextLayer *)map->GetParamBlock()->GetOwner();
|
||||
layer->RefreshBitmaps();
|
||||
layer->IChanged();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_INITIMAGE )
|
||||
{
|
||||
plPlasmaMAXLayer *layer = (plPlasmaMAXLayer *)map->GetParamBlock()->GetOwner();
|
||||
if( layer == nil )
|
||||
return FALSE;
|
||||
BOOL selectedNewBitmap = layer->HandleBitmapSelection();
|
||||
if( selectedNewBitmap )
|
||||
{
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
|
||||
ICustButton *bmSelectBtn = GetICustButton( GetDlgItem( hWnd, IDC_INITIMAGE ) );
|
||||
PBBitmap *pbbm = layer->GetPBBitmap();
|
||||
|
||||
bmSelectBtn->SetText( pbbm != nil ? (TCHAR *)pbbm->bi.Filename() : "");
|
||||
|
||||
ReleaseICustButton( bmSelectBtn );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
void DeleteThis() {};
|
||||
|
||||
protected:
|
||||
/// Clamp texture sizes to a power of 2
|
||||
void IClampTexSizeSpinner( TimeValue t, IParamMap2 *map, bool clampWidth )
|
||||
{
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
ParamID clampNew, clampOld;
|
||||
ParamID otherNew, otherOld;
|
||||
|
||||
if( clampWidth )
|
||||
{
|
||||
clampNew = plDynamicTextLayer::kBmpExportWidth; clampOld = plDynamicTextLayer::kBmpExportLastWidth;
|
||||
otherNew = plDynamicTextLayer::kBmpExportHeight; otherOld = plDynamicTextLayer::kBmpExportLastHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
clampNew = plDynamicTextLayer::kBmpExportHeight; clampOld = plDynamicTextLayer::kBmpExportLastHeight;
|
||||
otherNew = plDynamicTextLayer::kBmpExportWidth; otherOld = plDynamicTextLayer::kBmpExportLastWidth;
|
||||
}
|
||||
|
||||
int lastVal = pblock->GetInt( clampOld, t );
|
||||
int tempVal, newVal = pblock->GetInt( clampNew, t );
|
||||
|
||||
if( newVal < lastVal )
|
||||
{
|
||||
lastVal = newVal;
|
||||
for( tempVal = 1; tempVal <= newVal; tempVal <<= 1 );
|
||||
newVal = tempVal >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastVal = newVal;
|
||||
for( tempVal = 1; tempVal < newVal; tempVal <<= 1 );
|
||||
newVal = tempVal;
|
||||
}
|
||||
|
||||
pblock->SetValue( clampNew, t, newVal );
|
||||
pblock->SetValue( clampOld, t, newVal );
|
||||
}
|
||||
|
||||
int IFloorPow2( int value )
|
||||
{
|
||||
int v;
|
||||
|
||||
|
||||
for( v = 1; v <= value; v <<= 1 );
|
||||
return v >> 1;
|
||||
}
|
||||
};
|
||||
|
||||
static DTLBitmapDlgProc gDTLBitmapDlgProc;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// Bitmap Accessor //////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DTLPBAccessor : public PBAccessor
|
||||
{
|
||||
public:
|
||||
void Set(PB2Value& val, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t)
|
||||
{
|
||||
if( !owner )
|
||||
return;
|
||||
|
||||
plDynamicTextLayer *layer = (plDynamicTextLayer *)owner;
|
||||
|
||||
IParamBlock2 *pb = owner->GetParamBlockByID( plDynamicTextLayer::kBlkBitmap );
|
||||
switch( id )
|
||||
{
|
||||
case plDynamicTextLayer::kBmpInitBitmap:
|
||||
case plDynamicTextLayer::kBmpUseInitImage:
|
||||
if (pb->GetMap())
|
||||
pb->GetMap()->Invalidate( id );
|
||||
|
||||
layer->IChanged();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval &valid)
|
||||
{
|
||||
}
|
||||
};
|
||||
static DTLPBAccessor gDTLPBAccessor;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// ParamBlock Definition ////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static ParamBlockDesc2 gBitmapParamBlk
|
||||
(
|
||||
plDynamicTextLayer::kBlkBitmap, _T("bitmap"), 0, GetDynamicTextLayerDesc(),//NULL,
|
||||
P_AUTO_CONSTRUCT + P_AUTO_UI, plDynamicTextLayer::kRefBitmap,
|
||||
|
||||
IDD_DYN_TEXT_LAYER, IDS_DYN_TEXT_LAYER_PROPS, 0, 0, &gDTLBitmapDlgProc,
|
||||
|
||||
// Texture Color/Alpha
|
||||
plDynamicTextLayer::kBmpDiscardColor, _T("discardColor"), TYPE_BOOL, 0, 0,
|
||||
// p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_NO_COLOR,
|
||||
end,
|
||||
plDynamicTextLayer::kBmpInvertColor, _T("invertColor"), TYPE_BOOL, 0, 0,
|
||||
// p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_INV_COLOR,
|
||||
end,
|
||||
plDynamicTextLayer::kBmpDiscardAlpha, _T("discardAlpha"), TYPE_BOOL, 0, 0,
|
||||
// p_ui, TYPE_SINGLECHEKBOX, IDC_DISCARD_ALPHA,
|
||||
end,
|
||||
plDynamicTextLayer::kBmpInvertAlpha, _T("invertAlpha"), TYPE_BOOL, 0, 0,
|
||||
// p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_INV_ALPHA,
|
||||
end,
|
||||
|
||||
// Texture size
|
||||
plDynamicTextLayer::kBmpExportWidth, _T("exportWidth"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_EXPORTWIDTH, IDC_EXPORTWIDTH_SPINNER, SPIN_AUTOSCALE,
|
||||
p_range, 4, 2048,
|
||||
p_default, 512,
|
||||
end,
|
||||
plDynamicTextLayer::kBmpExportHeight, _T("exportHeight"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_EXPORTHEIGHT, IDC_EXPORTHEIGHT_SPINNER, SPIN_AUTOSCALE,
|
||||
p_range, 4, 2048,
|
||||
p_default, 512,
|
||||
end,
|
||||
plDynamicTextLayer::kBmpExportLastWidth, _T("lastExportWidth"), TYPE_INT, 0, 0,
|
||||
end,
|
||||
plDynamicTextLayer::kBmpExportLastHeight, _T("lastExportHeight"), TYPE_INT, 0, 0,
|
||||
end,
|
||||
|
||||
plDynamicTextLayer::kBmpIncludeAlphaChannel, _T("includeAlphaChannel"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_DYNTEXT_ALPHA,
|
||||
p_default, FALSE,
|
||||
end,
|
||||
|
||||
// Initial image
|
||||
plDynamicTextLayer::kBmpUseInitImage, _T("useInitImage"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_USEINITIMAGE,
|
||||
p_enable_ctrls, 1, plDynamicTextLayer::kBmpInitBitmap,
|
||||
p_accessor, &gDTLPBAccessor,
|
||||
end,
|
||||
plDynamicTextLayer::kBmpInitBitmap, _T("initBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0,
|
||||
p_accessor, &gDTLPBAccessor,
|
||||
end,
|
||||
|
||||
/* plGUIButtonComponent::kRefAnimate, _T( "animate" ), TYPE_BOOL, 0, 0,
|
||||
p_ui, plGUIControlBase::kRollMain, TYPE_SINGLECHEKBOX, IDC_GUI_ANIMATE,
|
||||
p_default, FALSE,
|
||||
p_enable_ctrls, 1, plGUIButtonComponent::kRefAnimation,
|
||||
end,
|
||||
|
||||
// Static text settings
|
||||
plDynamicTextLayer::kBmpMakeStatic, _T("makeStatic"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_DYNTEXT_MAKESTATIC,
|
||||
p_default, FALSE,
|
||||
p_enable_ctrls, 5, kBmpFontSize, kBmpLeftMargin, kBmpTopMargin, kBmpRightMargin, kBmpBottomMargin,
|
||||
end,
|
||||
|
||||
plDynamicTextLayer::kBmpText,
|
||||
plDynamicTextLayer::kBmpFontFace,
|
||||
plDynamicTextLayer::kBmpFontSize,
|
||||
plDynamicTextLayer::kBmpLeftMargin,
|
||||
plDynamicTextLayer::kBmpTopMargin,
|
||||
plDynamicTextLayer::kBmpRightMargin,
|
||||
plDynamicTextLayer::kBmpBottomMargin,
|
||||
*/
|
||||
end
|
||||
);
|
||||
|
@ -0,0 +1,683 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plLayerTex.h"
|
||||
|
||||
#include "iparamb2.h"
|
||||
#include "iparamm2.h"
|
||||
#include "stdmat.h"
|
||||
|
||||
#include "plBMSampler.h"
|
||||
#include "../resource.h"
|
||||
#include "plLayerTexBitmapPB.h"
|
||||
#include "../MaxMain/plPlasmaRefMsgs.h"
|
||||
|
||||
class plLayerTexClassDesc : public ClassDesc2
|
||||
{
|
||||
public:
|
||||
int IsPublic() { return TRUE; }
|
||||
void* Create(BOOL loading = FALSE) { return TRACKED_NEW plLayerTex(); }
|
||||
const TCHAR* ClassName() { return GetString(IDS_LAYER); }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
Class_ID ClassID() { return LAYER_TEX_CLASS_ID; }
|
||||
const TCHAR* Category() { return TEXMAP_CAT_2D; }
|
||||
const TCHAR* InternalName() { return _T("PlasmaLayer"); }
|
||||
HINSTANCE HInstance() { return hInstance; }
|
||||
};
|
||||
static plLayerTexClassDesc plLayerTexDesc;
|
||||
ClassDesc2* GetLayerTexDesc() { return &plLayerTexDesc; }
|
||||
|
||||
ParamDlg* plLayerTex::fUVGenDlg = NULL;
|
||||
|
||||
// For initializing paramblock descriptor
|
||||
//ParamBlockDesc2 *GetBasicBlk();
|
||||
ParamBlockDesc2 *GetBitmapBlk();
|
||||
|
||||
//#include "plLayerTexBasicPB.cpp"
|
||||
#include "plLayerTexBitmapPB.cpp"
|
||||
|
||||
void plLayerTex::GetClassName( TSTR &s )
|
||||
{
|
||||
s = GetString( IDS_LAYER );
|
||||
}
|
||||
|
||||
plLayerTex::plLayerTex() :
|
||||
fBitmapPB(NULL),
|
||||
//fBasicPB(NULL),
|
||||
fUVGen(NULL),
|
||||
fTexHandle(NULL),
|
||||
fTexTime(0),
|
||||
fBM(NULL),
|
||||
fIValid(NEVER)
|
||||
{
|
||||
#if 0
|
||||
// Initialize the paramblock descriptors only once
|
||||
static bool descInit = false;
|
||||
if (!descInit)
|
||||
{
|
||||
descInit = true;
|
||||
//GetBasicBlk()->SetClassDesc(GetLayerTexDesc());
|
||||
GetBitmapBlk()->SetClassDesc(GetLayerTexDesc());
|
||||
}
|
||||
#endif
|
||||
|
||||
plLayerTexDesc.MakeAutoParamBlocks(this);
|
||||
ReplaceReference(kRefUVGen, GetNewDefaultUVGen());
|
||||
}
|
||||
|
||||
plLayerTex::~plLayerTex()
|
||||
{
|
||||
if (fBM)
|
||||
fBM->DeleteThis();
|
||||
|
||||
IDiscardTexHandle();
|
||||
}
|
||||
|
||||
//From MtlBase
|
||||
void plLayerTex::Reset()
|
||||
{
|
||||
GetLayerTexDesc()->Reset(this, TRUE); // reset all pb2's
|
||||
SetBitmap(NULL);
|
||||
|
||||
fIValid.SetEmpty();
|
||||
}
|
||||
|
||||
void plLayerTex::Update(TimeValue t, Interval& valid)
|
||||
{
|
||||
if (!fIValid.InInterval(t))
|
||||
{
|
||||
fIValid.SetInfinite();
|
||||
|
||||
fUVGen->Update(t,fIValid);
|
||||
fBitmapPB->GetValidity(t, fIValid);
|
||||
|
||||
// Interval clipValid;
|
||||
// clipValid.SetInfinite();
|
||||
// float temp;
|
||||
// fBitmapPB->GetValue(kBmpClipU, t, temp, clipValid);
|
||||
// fBitmapPB->GetValue(kBmpClipV, t, temp, clipValid);
|
||||
// fBitmapPB->GetValue(kBmpClipW, t, temp, clipValid);
|
||||
// fBitmapPB->GetValue(kBmpClipH, t, temp, clipValid);
|
||||
}
|
||||
|
||||
// Gonna need to do this when we support animated bm's
|
||||
#if 0
|
||||
if (fBM)
|
||||
{
|
||||
if (bi.FirstFrame()!=bi.LastFrame())
|
||||
ivalid.SetInstant(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
valid &= fIValid;
|
||||
}
|
||||
|
||||
Interval plLayerTex::Validity(TimeValue t)
|
||||
{
|
||||
//TODO: Update fIValid here
|
||||
|
||||
// mf horse - Hacking this in just to get animations working.
|
||||
// No warranty on this not being stupid.
|
||||
Interval v = FOREVER;
|
||||
fBitmapPB->GetValidity(t, v);
|
||||
//fBasicPB->GetValidity(t, v);
|
||||
v &= fUVGen->Validity(t);
|
||||
return v;
|
||||
}
|
||||
|
||||
ParamDlg* plLayerTex::CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp)
|
||||
{
|
||||
fMtlParams = imp;
|
||||
|
||||
IAutoMParamDlg* masterDlg = plLayerTexDesc.CreateParamDlgs(hwMtlEdit, imp, this);
|
||||
|
||||
fUVGenDlg = fUVGen->CreateParamDlg(hwMtlEdit, imp);
|
||||
masterDlg->AddDlg(fUVGenDlg);
|
||||
|
||||
return masterDlg;
|
||||
}
|
||||
|
||||
BOOL plLayerTex::SetDlgThing(ParamDlg* dlg)
|
||||
{
|
||||
if (dlg == fUVGenDlg)
|
||||
{
|
||||
fUVGenDlg->SetThing(fUVGen);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int plLayerTex::NumRefs()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
//From ReferenceMaker
|
||||
RefTargetHandle plLayerTex::GetReference(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen: return fUVGen;
|
||||
case kRefBitmap: return fBitmapPB;
|
||||
//case kRefBasic: return fBasicPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void plLayerTex::SetReference(int i, RefTargetHandle rtarg)
|
||||
{
|
||||
Interval garbage;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen:
|
||||
fUVGen = (UVGen *)rtarg;
|
||||
if( fUVGen )
|
||||
fUVGen->Update( TimeValue( 0 ), garbage );
|
||||
break;
|
||||
case kRefBitmap:
|
||||
fBitmapPB = (IParamBlock2 *)rtarg;
|
||||
// KLUDGE: If the paramblock is being set chances are we are being created or
|
||||
// loaded. In the case of load, we want to refresh our texture.
|
||||
if (fBitmapPB)
|
||||
RefreshBitmaps();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int plLayerTex::NumParamBlocks()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
IParamBlock2* plLayerTex::GetParamBlock(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: return fBitmapPB;
|
||||
//case 1: return fBasicPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IParamBlock2* plLayerTex::GetParamBlockByID(BlockID id)
|
||||
{
|
||||
if (fBitmapPB->ID() == id)
|
||||
return fBitmapPB;
|
||||
//else if (fBasicPB->ID() == id)
|
||||
// return fBasicPB;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//From ReferenceTarget
|
||||
RefTargetHandle plLayerTex::Clone(RemapDir &remap)
|
||||
{
|
||||
plLayerTex *mnew = TRACKED_NEW plLayerTex();
|
||||
*((MtlBase*)mnew) = *((MtlBase*)this); // copy superclass stuff
|
||||
//mnew->ReplaceReference(kRefBasic, remap.CloneRef(fBasicPB));
|
||||
mnew->ReplaceReference(kRefBitmap, remap.CloneRef(fBitmapPB));
|
||||
mnew->ReplaceReference(kRefUVGen, remap.CloneRef(fUVGen));
|
||||
BaseClone(this, mnew, remap);
|
||||
return (RefTargetHandle)mnew;
|
||||
}
|
||||
|
||||
int plLayerTex::NumSubs()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
Animatable* plLayerTex::SubAnim(int i)
|
||||
{
|
||||
//TODO: Return 'i-th' sub-anim
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen: return fUVGen;
|
||||
case kRefBitmap: return fBitmapPB;
|
||||
//case kRefBasic: return fBasicPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TSTR plLayerTex::SubAnimName(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen: return "UVGen";
|
||||
case kRefBitmap: return fBitmapPB->GetLocalName();
|
||||
//case kRefBasic: return fBasicPB->GetLocalName();
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
RefResult plLayerTex::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case REFMSG_CHANGE:
|
||||
{
|
||||
fIValid.SetEmpty();
|
||||
|
||||
if (hTarget == fBitmapPB)
|
||||
{
|
||||
// see if this message came from a changing parameter in the pblock,
|
||||
// if so, limit rollout update to the changing item and update any active viewport texture
|
||||
ParamID changingParam = fBitmapPB->LastNotifyParamID();
|
||||
fBitmapPB->GetDesc()->InvalidateUI(changingParam);
|
||||
|
||||
if (changingParam != -1)
|
||||
IChanged();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case REFMSG_UV_SYM_CHANGE:
|
||||
IDiscardTexHandle();
|
||||
break;
|
||||
}
|
||||
|
||||
return REF_SUCCEED;
|
||||
}
|
||||
|
||||
BOOL plLayerTex::DiscardColor()
|
||||
{
|
||||
return fBitmapPB->GetInt(kBmpDiscardColor);
|
||||
}
|
||||
|
||||
BOOL plLayerTex::DiscardAlpha()
|
||||
{
|
||||
return fBitmapPB->GetInt(kBmpDiscardAlpha);
|
||||
}
|
||||
|
||||
void plLayerTex::IChanged()
|
||||
{
|
||||
IDiscardTexHandle();
|
||||
// Texture wasn't getting updated in the viewports, and this fixes it.
|
||||
// Don't know if it's the right way though.
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
|
||||
|
||||
// And this is so the SceneWatcher gets notified that the material on some of it's
|
||||
// referenced objects changed.
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_USER_MAT);
|
||||
}
|
||||
|
||||
#define TEX_HDR_CHUNK 0x5000
|
||||
#define MAX_ASS_CHUNK 0x5500
|
||||
|
||||
IOResult plLayerTex::Save(ISave *isave)
|
||||
{
|
||||
IOResult res;
|
||||
isave->BeginChunk(TEX_HDR_CHUNK);
|
||||
res = MtlBase::Save(isave);
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
isave->EndChunk();
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult plLayerTex::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
if (iload->CurChunkID() == TEX_HDR_CHUNK)
|
||||
{
|
||||
res = MtlBase::Load(iload);
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
bool plLayerTex::HasAlpha()
|
||||
{
|
||||
return (fBM != NULL && fBM->HasAlpha() != 0);
|
||||
}
|
||||
|
||||
Bitmap* plLayerTex::GetBitmap(TimeValue t)
|
||||
{
|
||||
return fBM;
|
||||
}
|
||||
|
||||
AColor plLayerTex::EvalColor(ShadeContext& sc)
|
||||
{
|
||||
if (!sc.doMaps)
|
||||
return AColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
AColor color;
|
||||
if (sc.GetCache(this, color))
|
||||
return color;
|
||||
|
||||
if (gbufID)
|
||||
sc.SetGBufferID(gbufID);
|
||||
|
||||
//
|
||||
// Evaluate the Bitmap
|
||||
//
|
||||
if (fBitmapPB->GetInt(kBmpUseBitmap) && fBM)
|
||||
{
|
||||
plBMSampler mysamp(this, fBM);
|
||||
color = fUVGen->EvalUVMap(sc, &mysamp, FALSE);
|
||||
// We'd like to pass TRUE and actually filter the image, but that seems to be
|
||||
// tripping an odd crash in Max internals. *shrug*
|
||||
}
|
||||
else
|
||||
color.White();
|
||||
|
||||
// Invert color if specified
|
||||
if (fBitmapPB->GetInt(kBmpInvertColor))
|
||||
{
|
||||
color.r = 1.0f - color.r;
|
||||
color.g = 1.0f - color.g;
|
||||
color.b = 1.0f - color.b;
|
||||
}
|
||||
// Discard color if specified
|
||||
if (fBitmapPB->GetInt(kBmpDiscardColor))
|
||||
color.r = color.g = color.b = 1.0f;
|
||||
|
||||
// Invert alpha if specified
|
||||
if (fBitmapPB->GetInt(kBmpInvertAlpha))
|
||||
color.a = 1.0f - color.a;
|
||||
// Discard alpha if specified
|
||||
if (fBitmapPB->GetInt(kBmpDiscardAlpha))
|
||||
color.a = 1.0f;
|
||||
|
||||
// If RGB output is set to alpha, show RGB as grayscale of the alpha
|
||||
if (fBitmapPB->GetInt(kBmpRGBOutput) == 1)
|
||||
color = AColor(color.a, color.a, color.a, 1.0f);
|
||||
|
||||
sc.PutCache(this, color);
|
||||
return color;
|
||||
}
|
||||
|
||||
float plLayerTex::EvalMono(ShadeContext& sc)
|
||||
{
|
||||
if (fBitmapPB->GetInt(kBmpMonoOutput) == 1)
|
||||
return EvalColor(sc).a;
|
||||
|
||||
return Intens(EvalColor(sc));
|
||||
}
|
||||
|
||||
Point3 plLayerTex::EvalNormalPerturb(ShadeContext& sc)
|
||||
{
|
||||
// Return the perturbation to apply to a normal for bump mapping
|
||||
return Point3(0, 0, 0);
|
||||
}
|
||||
|
||||
ULONG plLayerTex::LocalRequirements(int subMtlNum)
|
||||
{
|
||||
return fUVGen->Requirements(subMtlNum);
|
||||
}
|
||||
|
||||
#if 0
|
||||
int plLayerTex::ICalcFrame(TimeValue t)
|
||||
{
|
||||
PBBitmap *pbbm = fBitmapPB->GetBitmap(kBmpBitmap);
|
||||
if (!pbbm || !pbbm->bi)
|
||||
return 0;
|
||||
BitmapInfo *bi = pbbm->bi;
|
||||
|
||||
TimeValue tm, dur, td;
|
||||
int frameStart = bi->FirstFrame();
|
||||
int frameEnd = bi->LastFrame();
|
||||
int tpf = GetTicksPerFrame();
|
||||
tm = TimeValue(float(t - startTime) * pbRate);
|
||||
dur = (fend-fstart+1)*GetTicksPerFrame();
|
||||
|
||||
switch (endCond)
|
||||
{
|
||||
case END_HOLD:
|
||||
if (tm <= 0)
|
||||
return frameStart;
|
||||
if (tm >= dur)
|
||||
return frameEnd;
|
||||
return tm/tpf;
|
||||
|
||||
case END_PINGPONG:
|
||||
if (((tm >= 0) && ((tm / dur) & 1)) || ((tm < 0) && !(tm / dur)))
|
||||
{
|
||||
td = modt(tm, dur);
|
||||
return frameStart + frameEnd - td / tpf;
|
||||
}
|
||||
// else fall through
|
||||
case END_LOOP:
|
||||
td = modt(tm, dur);
|
||||
return td / tpf;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void plLayerTex::IDiscardTexHandle()
|
||||
{
|
||||
if (fTexHandle)
|
||||
{
|
||||
fTexHandle->DeleteThis();
|
||||
fTexHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void plLayerTex::ActivateTexDisplay(BOOL onoff)
|
||||
{
|
||||
if (!onoff)
|
||||
IDiscardTexHandle();
|
||||
}
|
||||
|
||||
BITMAPINFO *plLayerTex::GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono, BOOL forceW, BOOL forceH)
|
||||
{
|
||||
// FIXME
|
||||
fTexTime = 0;//CalcFrame(t);
|
||||
// texValid = clipValid;
|
||||
BITMAPINFO *bmi = NULL;
|
||||
int xflags = 0;
|
||||
|
||||
if (fBitmapPB->GetInt(kBmpApply))
|
||||
{
|
||||
float clipu = fBitmapPB->GetFloat(kBmpClipU);
|
||||
float clipv = fBitmapPB->GetFloat(kBmpClipV);
|
||||
float clipw = fBitmapPB->GetFloat(kBmpClipW);
|
||||
float cliph = fBitmapPB->GetFloat(kBmpClipH);
|
||||
int discardAlpha = fBitmapPB->GetInt(kBmpDiscardAlpha);
|
||||
int alphaAsRGB = (fBitmapPB->GetInt(kBmpRGBOutput) == 1);
|
||||
|
||||
int w = fBM->Width();
|
||||
int h = fBM->Height();
|
||||
|
||||
Bitmap *newBM;
|
||||
BitmapInfo bi;
|
||||
bi.SetName(_T("y8798734"));
|
||||
bi.SetType(BMM_TRUE_32);
|
||||
bi.SetFlags(MAP_HAS_ALPHA);
|
||||
|
||||
if (fBitmapPB->GetInt(kBmpCropPlace) == 1)
|
||||
{
|
||||
int x0, y0, nw, nh;
|
||||
int bmw = thmaker.Size();
|
||||
int bmh = int(float(bmw)*float(h)/float(w));
|
||||
bi.SetWidth(bmw);
|
||||
bi.SetHeight(bmh);
|
||||
newBM = TheManager->Create(&bi);
|
||||
newBM->Fill(0,0,0,0);
|
||||
nw = int(float(bmw)*clipw);
|
||||
nh = int(float(bmh)*cliph);
|
||||
x0 = int(float(bmw-1)*clipu);
|
||||
y0 = int(float(bmh-1)*clipv);
|
||||
|
||||
if (nw<1) nw = 1;
|
||||
if (nh<1) nh = 1;
|
||||
PixelBuf row(nw);
|
||||
|
||||
Bitmap *tmpBM;
|
||||
BitmapInfo bif2;
|
||||
bif2.SetName(_T("xxxx67878"));
|
||||
bif2.SetType(BMM_TRUE_32);
|
||||
bif2.SetFlags(MAP_HAS_ALPHA);
|
||||
bif2.SetWidth(nw);
|
||||
bif2.SetHeight(nh);
|
||||
tmpBM = TheManager->Create(&bif2);
|
||||
tmpBM->CopyImage(fBM, COPY_IMAGE_RESIZE_LO_QUALITY, 0);
|
||||
BMM_Color_64* p1 = row.Ptr();
|
||||
for (int y = 0; y<nh; y++)
|
||||
{
|
||||
tmpBM->GetLinearPixels(0,y, nw, p1);
|
||||
if (alphaAsRGB)
|
||||
{
|
||||
for (int ix =0; ix<nw; ix++)
|
||||
p1[ix].r = p1[ix].g = p1[ix].b = p1[ix].a;
|
||||
}
|
||||
if (discardAlpha)
|
||||
{
|
||||
for (int ix = 0; ix < nw; ix++)
|
||||
p1[ix].a = 0xffff;
|
||||
}
|
||||
newBM->PutPixels(x0, y+y0, nw, p1);
|
||||
}
|
||||
tmpBM->DeleteThis();
|
||||
bmi = thmaker.BitmapToDIB(newBM, fUVGen->SymFlags(), xflags, forceW, forceH);
|
||||
newBM->DeleteThis();
|
||||
}
|
||||
else
|
||||
{
|
||||
int x0,y0,nw,nh;
|
||||
x0 = int(float(w-1)*clipu);
|
||||
y0 = int(float(h-1)*clipv);
|
||||
nw = int(float(w)*clipw);
|
||||
nh = int(float(h)*cliph);
|
||||
if (nw<1) nw = 1;
|
||||
if (nh<1) nh = 1;
|
||||
bi.SetWidth(nw);
|
||||
bi.SetHeight(nh);
|
||||
PixelBuf row(nw);
|
||||
newBM = TheManager->Create(&bi);
|
||||
BMM_Color_64* p1 = row.Ptr();
|
||||
for (int y = 0; y<nh; y++)
|
||||
{
|
||||
fBM->GetLinearPixels(x0,y+y0, nw, p1);
|
||||
if (alphaAsRGB)
|
||||
{
|
||||
for (int ix = 0; ix < nw; ix++)
|
||||
p1[ix].r = p1[ix].g = p1[ix].b = p1[ix].a;
|
||||
}
|
||||
if (discardAlpha)
|
||||
{
|
||||
for (int ix = 0; ix < nw; ix++)
|
||||
p1[ix].a = 0xffff;
|
||||
}
|
||||
newBM->PutPixels(0, y, nw, p1);
|
||||
}
|
||||
bmi = thmaker.BitmapToDIB(newBM, fUVGen->SymFlags(), xflags, forceW, forceH);
|
||||
newBM->DeleteThis();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fBitmapPB->GetInt(kBmpRGBOutput) == 1)
|
||||
xflags |= EX_RGB_FROM_ALPHA;
|
||||
bmi = thmaker.BitmapToDIB(fBM, fUVGen->SymFlags(), xflags, forceW, forceH);
|
||||
}
|
||||
|
||||
return bmi;
|
||||
}
|
||||
|
||||
DWORD plLayerTex::GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker)
|
||||
{
|
||||
// FIXME: ignore validity for now
|
||||
if (fTexHandle && fIValid.InInterval(t))// && texTime == CalcFrame(t))
|
||||
return fTexHandle->GetHandle();
|
||||
else
|
||||
{
|
||||
IDiscardTexHandle();
|
||||
|
||||
fTexTime = 0;//CalcFrame(t);
|
||||
fTexHandle = thmaker.MakeHandle(GetVPDisplayDIB(t, thmaker, fIValid));
|
||||
if (fTexHandle)
|
||||
return fTexHandle->GetHandle();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char *plLayerTex::GetTextureName()
|
||||
{
|
||||
// if (fBitmapPB->GetInt(kBmpUseBitmap))
|
||||
{
|
||||
PBBitmap *pbbm = fBitmapPB->GetBitmap(kBmpBitmap);
|
||||
if (pbbm)
|
||||
return pbbm->bi.Name();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void plLayerTex::ISetPBBitmap(PBBitmap *pbbm, int index /* = 0 */)
|
||||
{
|
||||
fBitmapPB->SetValue(ParamID(kBmpBitmap), 0, pbbm, index);
|
||||
}
|
||||
|
||||
PBBitmap *plLayerTex::GetPBBitmap(int index /* = 0 */)
|
||||
{
|
||||
return fBitmapPB->GetBitmap(ParamID(kBmpBitmap));
|
||||
}
|
||||
|
||||
//// GetSamplerInfo ///////////////////////////////////////////////////////////
|
||||
// Virtual function called by plBMSampler to get various things while sampling
|
||||
// the layer's image
|
||||
|
||||
bool plLayerTex::GetSamplerInfo( plBMSamplerData *samplerData )
|
||||
{
|
||||
samplerData->fClipU = fBitmapPB->GetFloat( (ParamID)kBmpClipU );
|
||||
samplerData->fClipV = fBitmapPB->GetFloat( (ParamID)kBmpClipV );
|
||||
samplerData->fClipW = fBitmapPB->GetFloat( (ParamID)kBmpClipW );
|
||||
samplerData->fClipH = fBitmapPB->GetFloat( (ParamID)kBmpClipH );
|
||||
|
||||
samplerData->fEnableCrop = fBitmapPB->GetInt( (ParamID)kBmpApply ) ? true : false;
|
||||
samplerData->fCropPlacement = fBitmapPB->GetInt( (ParamID)kBmpCropPlace );
|
||||
|
||||
if( fBitmapPB->GetInt( (ParamID)kBmpDiscardAlpha ) )
|
||||
samplerData->fAlphaSource = plBMSamplerData::kDiscard;
|
||||
else if( fBitmapPB->GetInt( (ParamID)kBmpRGBOutput ) == 1 )
|
||||
samplerData->fAlphaSource = plBMSamplerData::kFromRGB;
|
||||
else
|
||||
samplerData->fAlphaSource = plBMSamplerData::kFromTexture;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void plLayerTex::SetExportSize(int x, int y)
|
||||
{
|
||||
fBitmapPB->SetValue(kBmpExportWidth, 0, x);
|
||||
fBitmapPB->SetValue(kBmpExportLastWidth, 0, x);
|
||||
fBitmapPB->SetValue(kBmpExportHeight, 0, y);
|
||||
fBitmapPB->SetValue(kBmpExportLastHeight, 0, y);
|
||||
}
|
||||
|
@ -0,0 +1,163 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
#ifndef __PLMAXLAYER__H
|
||||
#define __PLMAXLAYER__H
|
||||
|
||||
#include "Max.h"
|
||||
#include "plPlasmaMAXLayer.h"
|
||||
|
||||
class ClassDesc2;
|
||||
class IParamBlock2;
|
||||
class Bitmap;
|
||||
|
||||
ClassDesc2* GetLayerTexDesc();
|
||||
|
||||
extern TCHAR *GetString(int id);
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
class plLayerTex : public plPlasmaMAXLayer
|
||||
{
|
||||
protected:
|
||||
// Parameter block
|
||||
IParamBlock2 *fBitmapPB;
|
||||
IParamBlock2 *fBasicPB;
|
||||
UVGen *fUVGen;
|
||||
|
||||
IMtlParams *fMtlParams;
|
||||
|
||||
TexHandle *fTexHandle;
|
||||
TimeValue fTexTime;
|
||||
|
||||
Bitmap *fBM;
|
||||
static ParamDlg *fUVGenDlg;
|
||||
Interval fIValid;
|
||||
|
||||
friend class BitmapDlgProc;
|
||||
|
||||
public:
|
||||
// Ref nums
|
||||
enum
|
||||
{
|
||||
kRefUVGen,
|
||||
kRefBasic, // DEAD, but left in for backwards compatability
|
||||
kRefBitmap,
|
||||
};
|
||||
|
||||
// Block ID's
|
||||
enum
|
||||
{
|
||||
kBlkBasic, // DEAD
|
||||
kBlkBitmap,
|
||||
};
|
||||
|
||||
plLayerTex();
|
||||
~plLayerTex();
|
||||
void DeleteThis() { delete this; }
|
||||
|
||||
//From MtlBase
|
||||
ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
|
||||
BOOL SetDlgThing(ParamDlg* dlg);
|
||||
void Update(TimeValue t, Interval& valid);
|
||||
void Reset();
|
||||
Interval Validity(TimeValue t);
|
||||
ULONG LocalRequirements(int subMtlNum);
|
||||
|
||||
//From Texmap
|
||||
RGBA EvalColor(ShadeContext& sc);
|
||||
float EvalMono(ShadeContext& sc);
|
||||
Point3 EvalNormalPerturb(ShadeContext& sc);
|
||||
|
||||
// For displaying textures in the viewport
|
||||
BOOL SupportTexDisplay() { return TRUE; }
|
||||
void ActivateTexDisplay(BOOL onoff);
|
||||
BITMAPINFO *GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono=FALSE, int forceW=0, int forceH=0);
|
||||
DWORD GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
|
||||
protected:
|
||||
void IChanged();
|
||||
void IDiscardTexHandle();
|
||||
|
||||
public:
|
||||
void GetUVTransform(Matrix3 &uvtrans) { fUVGen->GetUVTransform(uvtrans); }
|
||||
int GetTextureTiling() { return fUVGen->GetTextureTiling(); }
|
||||
int GetUVWSource() { return fUVGen->GetUVWSource(); }
|
||||
virtual int GetMapChannel () { return fUVGen->GetMapChannel(); } // only relevant if above returns UVWSRC_EXPLICIT
|
||||
UVGen *GetTheUVGen() { return fUVGen; }
|
||||
|
||||
//TODO: Return anim index to reference index
|
||||
int SubNumToRefNum(int subNum) { return subNum; }
|
||||
|
||||
virtual BOOL DiscardColor();
|
||||
virtual BOOL DiscardAlpha();
|
||||
|
||||
// Loading/Saving
|
||||
IOResult Load(ILoad *iload);
|
||||
IOResult Save(ISave *isave);
|
||||
|
||||
//From Animatable
|
||||
Class_ID ClassID() { return LAYER_TEX_CLASS_ID; }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
void GetClassName(TSTR& s);
|
||||
|
||||
RefTargetHandle Clone( RemapDir &remap );
|
||||
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message);
|
||||
|
||||
int NumSubs();
|
||||
Animatable* SubAnim(int i);
|
||||
TSTR SubAnimName(int i);
|
||||
|
||||
// TODO: Maintain the number or references here
|
||||
int NumRefs();
|
||||
RefTargetHandle GetReference(int i);
|
||||
void SetReference(int i, RefTargetHandle rtarg);
|
||||
|
||||
int NumParamBlocks(); // return number of ParamBlocks in this instance
|
||||
IParamBlock2* GetParamBlock(int i); // return i'th ParamBlock
|
||||
IParamBlock2* GetParamBlockByID(BlockID id); // return id'd ParamBlock
|
||||
|
||||
bool HasAlpha(); // Checks if the bitmap for this layer has an alpha channel
|
||||
virtual Bitmap* GetBitmap(TimeValue t);
|
||||
|
||||
const char *GetTextureName();
|
||||
|
||||
// Accessors needed by the base class for the various bitmap related elements
|
||||
virtual Bitmap *GetMaxBitmap(int index = 0) { return fBM; }
|
||||
virtual PBBitmap *GetPBBitmap( int index = 0 );
|
||||
virtual int GetNumBitmaps( void ) { return 1; }
|
||||
|
||||
// Virtual function called by plBMSampler to get various things while sampling the layer's image
|
||||
virtual bool GetSamplerInfo( plBMSamplerData *samplerData );
|
||||
|
||||
// Backdoor for the texture find and replace util. Assumes input has the correct aspect ratio and is power of 2.
|
||||
virtual void SetExportSize(int x, int y);
|
||||
|
||||
protected:
|
||||
virtual void ISetPBBitmap( PBBitmap *pbbm, int index = 0 );
|
||||
virtual void ISetMaxBitmap(Bitmap *bitmap, int index = 0) { fBM = bitmap; }
|
||||
|
||||
};
|
||||
|
||||
#endif // __PLMAXLAYER__H
|
@ -0,0 +1,105 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plLayerTex.h"
|
||||
#include "plLayerTexBasicPB.h"
|
||||
|
||||
class BasicDlgProc;
|
||||
extern BasicDlgProc gBasicDlgProc;
|
||||
|
||||
static ParamBlockDesc2 gBasicParamBlk
|
||||
(
|
||||
plLayerTex::kBlkBasic, _T("basicLayer"), 0, GetLayerTexDesc(),//NULL,
|
||||
P_AUTO_CONSTRUCT + P_AUTO_UI, plLayerTex::kRefBasic,
|
||||
|
||||
// UI
|
||||
IDD_LAYER_BASIC, IDS_LAYER_BASIC, 0, 0, &gBasicDlgProc,
|
||||
|
||||
// Usage
|
||||
kBasicUsage, _T("usage"), TYPE_INT, 0, 0,
|
||||
end,
|
||||
|
||||
end
|
||||
);
|
||||
ParamBlockDesc2 *GetBasicBlk() { return &gBasicParamBlk; }
|
||||
|
||||
static const char *kUsageTypes[] =
|
||||
{
|
||||
"None",
|
||||
"Base Texture",
|
||||
"Detail",
|
||||
"Grime",
|
||||
"Map Blend",
|
||||
"Highlight/Specular",
|
||||
"Alpha Mask",
|
||||
"Shadow/Light Map",
|
||||
"Helper Object",
|
||||
"Best Guess"
|
||||
};
|
||||
|
||||
class BasicDlgProc : public ParamMap2UserDlgProc
|
||||
{
|
||||
public:
|
||||
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
IParamBlock2 *pb = map->GetParamBlock();
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
HWND hUsage = GetDlgItem(hWnd, IDC_USAGE_TYPE);
|
||||
for (int i = 0; i < kUsageNumTypes; i++)
|
||||
SendMessage(hUsage, CB_ADDSTRING, 0, (LPARAM)kUsageTypes[i]);
|
||||
SendMessage(hUsage, CB_SETCURSEL, pb->GetInt(kBasicUsage), 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (HIWORD(wParam))
|
||||
{
|
||||
case CBN_SELCHANGE:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_USAGE_TYPE:
|
||||
{
|
||||
int cur = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);
|
||||
if (LOWORD(wParam) == IDC_USAGE_TYPE)
|
||||
pb->SetValue(kBasicUsage, t, cur);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
void DeleteThis() {};
|
||||
};
|
||||
static BasicDlgProc gBasicDlgProc;
|
@ -0,0 +1,52 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
#ifndef PL_LAYERTEXBASICPB_H
|
||||
#define PL_LAYERTEXBASICPB_H
|
||||
|
||||
// Param ID's
|
||||
enum
|
||||
{
|
||||
kBasicUsage,
|
||||
};
|
||||
|
||||
// Usage types
|
||||
enum
|
||||
{
|
||||
kUsageNone,
|
||||
kUsageBase,
|
||||
kUsageDetail,
|
||||
kUsageGrime,
|
||||
kUsageTransition,
|
||||
kUsageHighlight,
|
||||
kUsageAlphaMask,
|
||||
kUsageShadowLight,
|
||||
kUsageHelper,
|
||||
kUsageGuess,
|
||||
|
||||
kUsageNumTypes
|
||||
};
|
||||
|
||||
#endif //PL_LAYERTEXBASICPB_H
|
@ -0,0 +1,751 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plLayerTex.h"
|
||||
#include "plLayerTexBitmapPB.h"
|
||||
#include "plDetailCurveCtrl.h"
|
||||
|
||||
#if 1
|
||||
class BMTexPBAccessor;
|
||||
extern BMTexPBAccessor bmtex_accessor;
|
||||
|
||||
class BitmapDlgProc;
|
||||
extern BitmapDlgProc gBitmapDlgProc;
|
||||
|
||||
static ParamBlockDesc2 gBitmapParamBlk
|
||||
(
|
||||
plLayerTex::kBlkBitmap, _T("bitmap"), 0, GetLayerTexDesc(),//NULL,
|
||||
P_AUTO_CONSTRUCT + P_AUTO_UI, plLayerTex::kRefBitmap,
|
||||
|
||||
IDD_LAYER_TEX, IDS_LAYER_TEX, 0, 0, &gBitmapDlgProc,
|
||||
|
||||
// Bitmap
|
||||
kBmpUseBitmap, _T("useBitmap"), TYPE_BOOL, 0, 0,
|
||||
p_default, TRUE,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_USE_BITMAP,
|
||||
end,
|
||||
kBmpBitmap, _T("bitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
|
||||
// Crop/Place
|
||||
kBmpApply, _T("apply"), TYPE_BOOL, 0, 0,
|
||||
p_default, FALSE,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_BM_CLIP,
|
||||
end,
|
||||
kBmpCropPlace, _T("cropPlace"), TYPE_INT, 0, 0,
|
||||
p_default, 0,
|
||||
p_range, 0, 1,
|
||||
p_ui, TYPE_RADIO, 2, IDC_BM_CROP,IDC_BM_PLACE,
|
||||
end,
|
||||
kBmpClipU, _T("clipU"), TYPE_FLOAT, P_ANIMATABLE, IDS_BITMAP_CLIPU,
|
||||
p_default, 0.0,
|
||||
p_range, 0.0, 1.0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_X, IDC_CLIP_XSPIN, 0.001f,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
kBmpClipV, _T("clipV"), TYPE_FLOAT, P_ANIMATABLE, IDS_BITMAP_CLIPV,
|
||||
p_default, 0.0,
|
||||
p_range, 0.0, 1.0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_Y, IDC_CLIP_YSPIN, 0.001f,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
kBmpClipW, _T("clipW"), TYPE_FLOAT, P_ANIMATABLE, IDS_BITMAP_CLIPW,
|
||||
p_default, 1.0,
|
||||
p_range, 0.0, 1.0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_W, IDC_CLIP_WSPIN, 0.001f,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
kBmpClipH, _T("clipH"), TYPE_FLOAT, P_ANIMATABLE, IDS_BITMAP_CLIPH,
|
||||
p_default, 1.0,
|
||||
p_range, 0.0, 1.0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_H, IDC_CLIP_HSPIN, 0.001f,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
|
||||
// Texture Color/Alpha
|
||||
kBmpDiscardColor, _T("discardColor"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_NO_COLOR,
|
||||
end,
|
||||
kBmpInvertColor, _T("invertColor"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_INV_COLOR,
|
||||
end,
|
||||
kBmpDiscardAlpha, _T("discardAlpha"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_DISCARD_ALPHA,
|
||||
end,
|
||||
kBmpInvertAlpha, _T("invertAlpha"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_INV_ALPHA,
|
||||
end,
|
||||
|
||||
// Texture Quality
|
||||
kBmpNonCompressed, _T("nonCompressed"),TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_FORCE_NONCOMPRESSED,
|
||||
end,
|
||||
kBmpScaling, _T("scaling"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_RADIO, 3, IDC_SCALE_ALL, IDC_SCALE_HALF, IDC_SCALE_NONE,
|
||||
end,
|
||||
|
||||
// Max Only
|
||||
kBmpMonoOutput, _T("monoOutput"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_RADIO, 2, IDC_HSMAX_LAYER_RGBOUT, IDC_HSMAX_LAYER_ALPHAOUT,
|
||||
end,
|
||||
kBmpRGBOutput, _T("rgbOutput"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_RADIO, 2, IDC_HSMAX_LAYER_RGBOUT2, IDC_HSMAX_LAYER_ALPHAOUT2,
|
||||
end,
|
||||
|
||||
// Mipmap
|
||||
kBmpNoFilter, _T("noFilter"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_NO_FILTERING,
|
||||
end,
|
||||
kBmpMipBlur, _T("mipBlur"), TYPE_FLOAT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_MIPBLUR_EDIT, IDC_MIPBLUR_SPIN, 0.4,
|
||||
p_range, 0.01f, 100.0f,
|
||||
p_default, 1.0,
|
||||
end,
|
||||
kBmpMipBias, _T("mipBias"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_USE_MIPBIAS,
|
||||
p_enable_ctrls, 1, kBmpMipBiasAmt,
|
||||
end,
|
||||
kBmpMipBiasAmt, _T("mipBiasAmt"), TYPE_FLOAT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_MIPBIAS_EDIT, IDC_MIPBIAS_SPIN, 0.7,
|
||||
p_range, -100.0, 100.0,
|
||||
p_default, 1.0,
|
||||
end,
|
||||
|
||||
// Detail
|
||||
kBmpUseDetail, _T("useDetail"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_USE_DETAIL,
|
||||
p_default, FALSE,
|
||||
p_enable_ctrls, 4, kBmpDetailStartSize, kBmpDetailStopSize, kBmpDetailStartOpac, kBmpDetailStopOpac,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
|
||||
kBmpDetailStartSize,_T("dropOffStart"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_START_SIZE_EDIT, IDC_DETAIL_START_SIZE_SPIN, 0.4,
|
||||
p_range, 0, 100,
|
||||
p_default, 0,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
kBmpDetailStopSize, _T("dropOffStop"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_STOP_SIZE_EDIT, IDC_DETAIL_STOP_SIZE_SPIN, 0.4,
|
||||
p_range, 0, 100,
|
||||
p_default, 100,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
kBmpDetailStartOpac, _T("detailMax"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_START_OPAC_EDIT, IDC_DETAIL_START_OPAC_SPIN, 0.4,
|
||||
p_range, 0, 100,
|
||||
p_default, 100,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
kBmpDetailStopOpac, _T("detailMin"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_STOP_OPAC_EDIT, IDC_DETAIL_STOP_OPAC_SPIN, 0.4,
|
||||
p_range, 0, 100,
|
||||
p_default, 0,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
|
||||
kBmpExportWidth, _T("exportWidth"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_EXPORTWIDTH, IDC_EXPORTWIDTH_SPINNER, SPIN_AUTOSCALE,
|
||||
p_range, 4, 2048,
|
||||
p_default, 512,
|
||||
end,
|
||||
kBmpExportHeight, _T("exportHeight"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_EXPORTHEIGHT, IDC_EXPORTHEIGHT_SPINNER, SPIN_AUTOSCALE,
|
||||
p_range, 4, 2048,
|
||||
p_default, 512,
|
||||
end,
|
||||
kBmpExportLastWidth, _T("lastExportWidth"), TYPE_INT, 0, 0,
|
||||
end,
|
||||
kBmpExportLastHeight, _T("lastExportHeight"), TYPE_INT, 0, 0,
|
||||
end,
|
||||
|
||||
// Keep a sysmem copy at runtime (for image examination/manipulation).
|
||||
kBmpNoDiscard, _T("noDiscard"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_NO_DISCARD,
|
||||
p_default, FALSE,
|
||||
end,
|
||||
|
||||
end
|
||||
);
|
||||
ParamBlockDesc2 *GetBitmapBlk() { return &gBitmapParamBlk; }
|
||||
|
||||
class BMCropper;
|
||||
|
||||
class BMTexPBAccessor : public PBAccessor
|
||||
{
|
||||
public:
|
||||
void Set(PB2Value& val, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t)
|
||||
{
|
||||
plLayerTex* layer = (plLayerTex*)owner;
|
||||
|
||||
if(layer == NULL) return;
|
||||
|
||||
IParamBlock2 *pb = layer->GetParamBlockByID(plLayerTex::kBlkBitmap);
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case kBmpBitmap:
|
||||
if (pb->GetMap())
|
||||
pb->GetMap()->Invalidate(kBmpBitmap);
|
||||
|
||||
// Update the bitmap saved by the layer
|
||||
//layer->SetBitmap(&val.bm->bi, tabIndex);
|
||||
break;
|
||||
|
||||
/*
|
||||
case kBmpFilename:
|
||||
bmt->SetMapName(val.s);
|
||||
break;
|
||||
|
||||
case kBmpFiltering:
|
||||
bmt->filterType = val.i;
|
||||
if (bmt->thebm)
|
||||
bmt->thebm->SetFilter(bmFilterType(val.i));
|
||||
break;
|
||||
*/
|
||||
case kBmpClipU:
|
||||
{
|
||||
float u = val.f;
|
||||
float w = pb->GetFloat(kBmpClipW, t);
|
||||
if (u + w > 1.0f)
|
||||
{
|
||||
pb->SetValue(kBmpClipW, t, 1.0f-u);
|
||||
if (pb->GetMap())
|
||||
pb->GetMap()->Invalidate(kBmpClipW);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kBmpClipW:
|
||||
{
|
||||
float w = val.f;
|
||||
float u = pb->GetFloat(kBmpClipU, t);
|
||||
if (u + w > 1.0f)
|
||||
{
|
||||
pb->SetValue(kBmpClipU, t, 1.0f-w);
|
||||
if (pb->GetMap())
|
||||
pb->GetMap()->Invalidate(kBmpClipU);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kBmpClipV:
|
||||
{
|
||||
float v = val.f;
|
||||
float h = pb->GetFloat(kBmpClipH, t);
|
||||
if (v + h > 1.0f)
|
||||
{
|
||||
pb->SetValue(kBmpClipH, t, 1.0f-v);
|
||||
if (pb->GetMap())
|
||||
pb->GetMap()->Invalidate(kBmpClipH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kBmpClipH:
|
||||
{
|
||||
float h = val.f;
|
||||
float v = pb->GetFloat(kBmpClipV, t);
|
||||
if (v + h > 1.0f)
|
||||
{
|
||||
pb->SetValue(kBmpClipV, t, 1.0f-h);
|
||||
if (pb->GetMap())
|
||||
pb->GetMap()->Invalidate(kBmpClipV);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kBmpDetailStartSize:
|
||||
case kBmpDetailStopSize:
|
||||
case kBmpDetailStartOpac:
|
||||
case kBmpDetailStopOpac:
|
||||
if( pb != NULL )
|
||||
{
|
||||
if( IIsProcSettingDetailValues( pb ) )
|
||||
break; // Ignore, since we're the ones setting 'em
|
||||
|
||||
HWND dlg = pb->GetMap()->GetHWnd();
|
||||
plDetailCurveCtrl *ctrl = GET_DETAIL_CURVE_CTRL( dlg, IDC_DETAIL_CURVE_CTRL );
|
||||
if( ctrl != NULL )
|
||||
{
|
||||
if( id == kBmpDetailStartSize || id == kBmpDetailStartOpac )
|
||||
ctrl->SetStartPoint( (float)pb->GetInt( kBmpDetailStartSize, t ) / 100.f,
|
||||
(float)pb->GetInt( kBmpDetailStartOpac, t ) / 100.f );
|
||||
else
|
||||
ctrl->SetEndPoint( (float)pb->GetInt( kBmpDetailStopSize, t ) / 100.f,
|
||||
(float)pb->GetInt( kBmpDetailStopOpac, t ) / 100.f );
|
||||
}
|
||||
|
||||
// Make sure start is less than end
|
||||
if( id == kBmpDetailStartSize )
|
||||
{
|
||||
int end = pb->GetInt( kBmpDetailStopSize, t );
|
||||
if( val.i > end )
|
||||
pb->SetValue( kBmpDetailStopSize, t, val.i );
|
||||
}
|
||||
else if( id == kBmpDetailStopSize )
|
||||
{
|
||||
int start = pb->GetInt( kBmpDetailStartSize, t );
|
||||
if( val.i < start )
|
||||
pb->SetValue( kBmpDetailStartSize, t, val.i );
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case kBmpUseDetail:
|
||||
if( pb != NULL )
|
||||
{
|
||||
HWND dlg = pb->GetMap()->GetHWnd();
|
||||
EnableWindow( GetDlgItem( dlg, IDC_DETAIL_CURVE_CTRL ), (BOOL)val.i );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval &valid)
|
||||
{
|
||||
}
|
||||
|
||||
// Gotta love hacks....
|
||||
bool IIsProcSettingDetailValues( IParamBlock2 *pb );
|
||||
|
||||
};
|
||||
static BMTexPBAccessor bmtex_accessor;
|
||||
|
||||
|
||||
//=========================================================================================
|
||||
// BMCropper
|
||||
//=========================================================================================
|
||||
class BMCropper : public CropCallback
|
||||
{
|
||||
IParamBlock2 *fPBlock;
|
||||
|
||||
public:
|
||||
BMCropper(IParamBlock2* pblock) : fPBlock(pblock) {}
|
||||
|
||||
float GetInitU() { return fPBlock->GetFloat(kBmpClipU); }
|
||||
float GetInitV() { return fPBlock->GetFloat(kBmpClipV); }
|
||||
float GetInitW() { return fPBlock->GetFloat(kBmpClipW); }
|
||||
float GetInitH() { return fPBlock->GetFloat(kBmpClipH); }
|
||||
BOOL GetInitMode() { return fPBlock->GetInt(kBmpCropPlace); }
|
||||
void SetValues(float u, float v, float w, float h, BOOL md);
|
||||
void OnClose();
|
||||
};
|
||||
|
||||
void BMCropper::SetValues(float u, float v, float w, float h, BOOL md)
|
||||
{
|
||||
TimeValue t = GetCOREInterface()->GetTime();
|
||||
|
||||
if (u != fPBlock->GetFloat(kBmpClipU, t))
|
||||
{
|
||||
fPBlock->SetValue(kBmpClipU, t, u);
|
||||
fPBlock->GetMap()->Invalidate(kBmpClipU);
|
||||
}
|
||||
|
||||
if (v != fPBlock->GetFloat(kBmpClipV, t))
|
||||
{
|
||||
fPBlock->SetValue(kBmpClipV, t, v);
|
||||
fPBlock->GetMap()->Invalidate(kBmpClipV);
|
||||
}
|
||||
|
||||
if (w != fPBlock->GetFloat(kBmpClipW, t))
|
||||
{
|
||||
fPBlock->SetValue(kBmpClipW, t, w);
|
||||
fPBlock->GetMap()->Invalidate(kBmpClipW);
|
||||
}
|
||||
|
||||
if (h != fPBlock->GetFloat(kBmpClipH, t))
|
||||
{
|
||||
fPBlock->SetValue(kBmpClipH, t, h);
|
||||
fPBlock->GetMap()->Invalidate(kBmpClipH);
|
||||
}
|
||||
|
||||
if (md != fPBlock->GetInt(kBmpCropPlace))
|
||||
{
|
||||
fPBlock->SetValue(kBmpCropPlace, t, md);
|
||||
fPBlock->GetMap()->Invalidate(kBmpCropPlace);
|
||||
}
|
||||
}
|
||||
|
||||
void BMCropper::OnClose()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
class BitmapDlgProc : public ParamMap2UserDlgProc
|
||||
{
|
||||
friend class BMTexPBAccessor;
|
||||
|
||||
|
||||
PBBitmap *fLastBMap;
|
||||
bool fSettingDetailValues;
|
||||
|
||||
|
||||
/// Called to update the controls of the dialog
|
||||
/// Note: we're bad that we use a static here, but
|
||||
virtual void Update( TimeValue t, Interval &valid, IParamMap2 *map )
|
||||
{
|
||||
ICustButton *bmSelectBtn;
|
||||
IParamBlock2 *pblock;
|
||||
int width, height;
|
||||
|
||||
|
||||
ParamMap2UserDlgProc::Update( t, valid, map );
|
||||
|
||||
if( fSettingDetailValues )
|
||||
{
|
||||
// We're getting an update just because we changed detail values, so we
|
||||
// know we don't have to do anything ourselves
|
||||
return;
|
||||
}
|
||||
|
||||
pblock = map->GetParamBlock();
|
||||
|
||||
// Update texture map button
|
||||
bmSelectBtn = GetICustButton( GetDlgItem( map->GetHWnd(), IDC_LAYER_NAME ) );
|
||||
PBBitmap *pbbm = pblock->GetBitmap( kBmpBitmap, t );
|
||||
if( pbbm )
|
||||
{
|
||||
if( pbbm != fLastBMap )
|
||||
{
|
||||
bmSelectBtn->SetText( (TCHAR *)pbbm->bi.Filename() );
|
||||
|
||||
// Init values for clamping spinners to powers of 2
|
||||
width = IFloorPow2( pbbm->bi.Width() );
|
||||
map->SetRange( kBmpExportWidth, 4.f, (float)width );
|
||||
|
||||
height = IFloorPow2( pbbm->bi.Height() );
|
||||
map->SetRange( kBmpExportHeight, 4.f, (float)height );
|
||||
|
||||
IClampTexSizeSpinner( t, map, true );
|
||||
ISetDetailCurveNumLevels( map, t );
|
||||
}
|
||||
}
|
||||
else if( pbbm != fLastBMap )
|
||||
bmSelectBtn->SetText( _T( "None" ) );
|
||||
|
||||
fLastBMap = pbbm;
|
||||
|
||||
ReleaseICustButton( bmSelectBtn );
|
||||
|
||||
// Update detail curve control
|
||||
HWND dlg = map->GetHWnd();
|
||||
|
||||
plDetailCurveCtrl *ctrl = GET_DETAIL_CURVE_CTRL( dlg, IDC_DETAIL_CURVE_CTRL );
|
||||
if( ctrl == NULL )
|
||||
{
|
||||
// The control hasn't been created, so create it already!
|
||||
HWND basis;
|
||||
RECT r;
|
||||
|
||||
// Create the detail map control
|
||||
basis = GetDlgItem( dlg, IDC_DETAIL_SAMPLE );
|
||||
GetClientRect( basis, &r );
|
||||
MapWindowPoints( basis, dlg, (POINT *)&r, 2 );
|
||||
|
||||
ctrl = TRACKED_NEW plDetailCurveCtrl( dlg, IDC_DETAIL_CURVE_CTRL, &r );
|
||||
}
|
||||
|
||||
EnableWindow( GetDlgItem( dlg, IDC_DETAIL_CURVE_CTRL ), (BOOL)pblock->GetInt( kBmpUseDetail, t ) );
|
||||
|
||||
if( ctrl != NULL )
|
||||
{
|
||||
ctrl->SetStartPoint( (float)pblock->GetInt( kBmpDetailStartSize, t ) / 100.f,
|
||||
(float)pblock->GetInt( kBmpDetailStartOpac, t ) / 100.f );
|
||||
ctrl->SetEndPoint( (float)pblock->GetInt( kBmpDetailStopSize, t ) / 100.f,
|
||||
(float)pblock->GetInt( kBmpDetailStopOpac, t ) / 100.f );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static ICustButton* bmSelectBtn;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
fLastBMap = NULL;
|
||||
fSettingDetailValues = false;
|
||||
break;
|
||||
|
||||
/// Note: the following *could* be done in the accessor, except that you end up in an
|
||||
/// infinite loop updating the values. Not good.
|
||||
case CC_SPINNER_CHANGE:
|
||||
|
||||
if( LOWORD( wParam ) == IDC_EXPORTWIDTH_SPINNER )
|
||||
IClampTexSizeSpinner( t, map, true );
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_EXPORTHEIGHT_SPINNER )
|
||||
IClampTexSizeSpinner( t, map, false );
|
||||
|
||||
break;
|
||||
|
||||
// Message from the detail curve that a point got dragged
|
||||
case PL_DC_POINT_DRAGGED:
|
||||
{
|
||||
plDetailCurveCtrl *ctrl = (plDetailCurveCtrl *)lParam;
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
float x, y;
|
||||
|
||||
|
||||
fSettingDetailValues = true;
|
||||
|
||||
if( wParam == PL_DC_START_POINT )
|
||||
{
|
||||
ctrl->GetStartPoint( x, y );
|
||||
pblock->SetValue( kBmpDetailStartSize, t, (int)( x * 100.f ) );
|
||||
pblock->SetValue( kBmpDetailStartOpac, t, (int)( y * 100.f ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
ctrl->GetEndPoint( x, y );
|
||||
pblock->SetValue( kBmpDetailStopSize, t, (int)( x * 100.f ) );
|
||||
pblock->SetValue( kBmpDetailStopOpac, t, (int)( y * 100.f ) );
|
||||
}
|
||||
|
||||
map->UpdateUI( t );
|
||||
fSettingDetailValues = false;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_COMMAND:
|
||||
if( HIWORD( wParam ) == EN_CHANGE && LOWORD( wParam ) == IDC_EXPORTWIDTH )
|
||||
IClampTexSizeSpinner( t, map, true );
|
||||
|
||||
else if( HIWORD( wParam ) == EN_CHANGE && LOWORD( wParam ) == IDC_EXPORTHEIGHT )
|
||||
IClampTexSizeSpinner( t, map, false );
|
||||
|
||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_BM_CROP_IMAGE)
|
||||
{
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
PBBitmap *pbbm = pblock->GetBitmap(kBmpBitmap, t);
|
||||
if (pbbm)
|
||||
{
|
||||
if (!pbbm->bm)
|
||||
pbbm->bm = TheManager->Load(&pbbm->bi);
|
||||
|
||||
BMCropper *cropper = TRACKED_NEW BMCropper(pblock);
|
||||
|
||||
pbbm->bm->Display("Specify Cropping/Placement", BMM_CN, FALSE, TRUE, cropper);
|
||||
}
|
||||
// bm->DeleteThis();
|
||||
return TRUE;
|
||||
}
|
||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_LAYER_RELOAD)
|
||||
{
|
||||
// TEMP
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
PBBitmap *pbbm = pblock->GetBitmap(kBmpBitmap, t);
|
||||
if (pbbm)
|
||||
{
|
||||
plLayerTex *layer = (plLayerTex*)map->GetParamBlock()->GetOwner();
|
||||
|
||||
layer->RefreshBitmaps();
|
||||
|
||||
layer->fMtlParams->MtlChanged();
|
||||
layer->IChanged();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else if (LOWORD(wParam) == IDC_LAYER_NAME)
|
||||
{
|
||||
plPlasmaMAXLayer *layer = (plPlasmaMAXLayer *)map->GetParamBlock()->GetOwner();
|
||||
if (layer == nil)
|
||||
return FALSE;
|
||||
BOOL selectedNewBitmap = layer->HandleBitmapSelection();
|
||||
|
||||
if(selectedNewBitmap)
|
||||
{
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
//plLayerTex *layer = (plLayerTex*)map->GetParamBlock()->GetOwner();
|
||||
|
||||
//layer->SetBitmap(&bi);
|
||||
//layer->IChanged();
|
||||
//BitmapInfo *bi = &layer->GetPBBitmap()->bi;
|
||||
|
||||
bmSelectBtn = GetICustButton(GetDlgItem(hWnd,IDC_LAYER_NAME));
|
||||
PBBitmap *pbbm = layer->GetPBBitmap();
|
||||
bmSelectBtn->SetText(pbbm != nil ? (TCHAR*)pbbm->bi.Filename() : "");
|
||||
ReleaseICustButton(bmSelectBtn);
|
||||
|
||||
if (pbbm != nil)
|
||||
{
|
||||
// Init values for clamping spinners to powers of 2
|
||||
int width = IFloorPow2( pbbm->bi.Width() );
|
||||
map->SetRange( kBmpExportWidth, 4.f, (float)width );
|
||||
|
||||
int height = IFloorPow2( pbbm->bi.Height() );
|
||||
map->SetRange( kBmpExportHeight, 4.f, (float)height );
|
||||
|
||||
if( width > 512 )
|
||||
{
|
||||
height = (int)( 512.f * (float)( (float)height / (float)width ) );
|
||||
width = 512;
|
||||
}
|
||||
else if( height > 512 )
|
||||
{
|
||||
width = (int)( 512.f * (float)( (float)width / (float)height ) );
|
||||
height = 512;
|
||||
}
|
||||
pblock->SetValue( kBmpExportWidth, t, width );
|
||||
pblock->SetValue( kBmpExportLastWidth, t, width );
|
||||
pblock->SetValue( kBmpExportHeight, t, height );
|
||||
pblock->SetValue( kBmpExportLastHeight, t, height );
|
||||
|
||||
IClampTexSizeSpinner( t, map, true );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
void DeleteThis() {};
|
||||
|
||||
void ISetDetailCurveNumLevels( IParamMap2 *map, TimeValue t )
|
||||
{
|
||||
/// Set the level count on the detail control
|
||||
plDetailCurveCtrl *ctrl = GET_DETAIL_CURVE_CTRL( map->GetHWnd(), IDC_DETAIL_CURVE_CTRL );
|
||||
if( ctrl != NULL )
|
||||
{
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
int w = pblock->GetInt( kBmpExportWidth, t );
|
||||
int h = pblock->GetInt( kBmpExportHeight, t );
|
||||
int numLevels = 0;
|
||||
while( w > 1 && h > 1 )
|
||||
{
|
||||
w >>= 1;
|
||||
h >>= 1;
|
||||
numLevels++;
|
||||
}
|
||||
ctrl->SetNumLevels( numLevels );
|
||||
}
|
||||
}
|
||||
|
||||
/// Clamp texture sizes to a power of 2
|
||||
void IClampTexSizeSpinner( TimeValue t, IParamMap2 *map, bool clampWidth )
|
||||
{
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
ParamID clampNew, clampOld;
|
||||
ParamID otherNew, otherOld;
|
||||
|
||||
if( clampWidth )
|
||||
{
|
||||
clampNew = kBmpExportWidth; clampOld = kBmpExportLastWidth;
|
||||
otherNew = kBmpExportHeight; otherOld = kBmpExportLastHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
clampNew = kBmpExportHeight; clampOld = kBmpExportLastHeight;
|
||||
otherNew = kBmpExportWidth; otherOld = kBmpExportLastWidth;
|
||||
}
|
||||
|
||||
int lastVal = pblock->GetInt( clampOld, t );
|
||||
int tempVal, newVal = pblock->GetInt( clampNew, t );
|
||||
|
||||
if( newVal < lastVal )
|
||||
{
|
||||
lastVal = newVal;
|
||||
for( tempVal = 1; tempVal <= newVal; tempVal <<= 1 );
|
||||
newVal = tempVal >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastVal = newVal;
|
||||
for( tempVal = 1; tempVal < newVal; tempVal <<= 1 );
|
||||
newVal = tempVal;
|
||||
}
|
||||
|
||||
pblock->SetValue( clampNew, t, newVal );
|
||||
pblock->SetValue( clampOld, t, newVal );
|
||||
|
||||
// And clamp aspect ratio
|
||||
PBBitmap *pbbm = pblock->GetBitmap( kBmpBitmap, t );
|
||||
|
||||
if( pbbm != NULL )
|
||||
{
|
||||
int realWidth = pbbm->bi.Width();
|
||||
int realHeight = pbbm->bi.Height();
|
||||
|
||||
float aspect;
|
||||
if( clampWidth )
|
||||
aspect = (float)realHeight / (float)realWidth;
|
||||
else
|
||||
aspect = (float)realWidth / (float)realHeight;
|
||||
|
||||
int value = newVal;
|
||||
value *= aspect;
|
||||
|
||||
if( value < 4 )
|
||||
{
|
||||
// Can't be below 4!
|
||||
value = 4;
|
||||
pblock->SetValue( otherNew, t, value );
|
||||
pblock->SetValue( otherOld, t, value );
|
||||
value = value / aspect;
|
||||
pblock->SetValue( clampNew, t, value );
|
||||
pblock->SetValue( clampOld, t, value );
|
||||
}
|
||||
else
|
||||
{
|
||||
pblock->SetValue( otherNew, t, value );
|
||||
pblock->SetValue( otherOld, t, value );
|
||||
}
|
||||
}
|
||||
|
||||
ISetDetailCurveNumLevels( map, t );
|
||||
}
|
||||
|
||||
int IFloorPow2( int value )
|
||||
{
|
||||
int v;
|
||||
|
||||
|
||||
for( v = 1; v <= value; v <<= 1 );
|
||||
return v >> 1;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static BitmapDlgProc gBitmapDlgProc;
|
||||
|
||||
|
||||
// Gotta love hacks....
|
||||
bool BMTexPBAccessor::IIsProcSettingDetailValues( IParamBlock2 *pb )
|
||||
{
|
||||
BitmapDlgProc *proc = (BitmapDlgProc *)pb->GetMap()->GetUserDlgProc();
|
||||
if( proc != NULL )
|
||||
return proc->fSettingDetailValues;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,87 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
#ifndef PL_LAYERTEXBITMAPPB_H
|
||||
#define PL_LAYERTEXBITMAPPB_H
|
||||
|
||||
// Param ID's
|
||||
enum
|
||||
{
|
||||
kBmpUseBitmap,
|
||||
kBmpBitmap,
|
||||
|
||||
// Cropping/Placement
|
||||
kBmpApply,
|
||||
kBmpCropPlace,
|
||||
kBmpClipU,
|
||||
kBmpClipV,
|
||||
kBmpClipW,
|
||||
kBmpClipH,
|
||||
|
||||
// Misc
|
||||
kBmpDiscardColor,
|
||||
kBmpInvertColor,
|
||||
kBmpDiscardAlpha,
|
||||
kBmpInvertAlpha,
|
||||
|
||||
// Texture quality
|
||||
kBmpNonCompressed,
|
||||
kBmpScaling,
|
||||
|
||||
// Mipmap
|
||||
kBmpNoFilter,
|
||||
kBmpMipBlur,
|
||||
kBmpMipBias,
|
||||
kBmpMipBiasAmt,
|
||||
|
||||
// Max only
|
||||
kBmpMonoOutput,
|
||||
kBmpRGBOutput,
|
||||
|
||||
// Detail
|
||||
kBmpUseDetail,
|
||||
kBmpDetailStartSize,
|
||||
kBmpDetailStopSize,
|
||||
kBmpDetailStartOpac,
|
||||
kBmpDetailStopOpac,
|
||||
|
||||
// New export size controls
|
||||
kBmpExportWidth,
|
||||
kBmpExportHeight,
|
||||
kBmpExportLastWidth, // Annoying fields, these two, but they're necessary
|
||||
kBmpExportLastHeight, // for clamping the spinners to powers of 2
|
||||
|
||||
// Keep a sysmem copy of the texture
|
||||
kBmpNoDiscard
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kScalingAny,
|
||||
kScalingHalf,
|
||||
kScalingNone
|
||||
};
|
||||
|
||||
#endif //PL_LAYERTEXBITMAPPB_H
|
@ -0,0 +1,399 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "plMAXCameraLayer.h"
|
||||
|
||||
#include "iparamb2.h"
|
||||
#include "iparamm2.h"
|
||||
#include "stdmat.h"
|
||||
|
||||
#include "plBMSampler.h"
|
||||
#include "../MaxMain/plPlasmaRefMsgs.h"
|
||||
|
||||
class plMAXCameraLayerClassDesc : public ClassDesc2
|
||||
{
|
||||
public:
|
||||
int IsPublic() { return TRUE; }
|
||||
void* Create(BOOL loading = FALSE) { return TRACKED_NEW plMAXCameraLayer(); }
|
||||
const TCHAR* ClassName() { return GetString(IDS_MAX_CAMERA_LAYER); }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
Class_ID ClassID() { return MAX_CAMERA_LAYER_CLASS_ID; }
|
||||
const TCHAR* Category() { return TEXMAP_CAT_COLMOD; }
|
||||
const TCHAR* InternalName() { return _T("PlasmaMAXCameraLayer"); }
|
||||
HINSTANCE HInstance() { return hInstance; }
|
||||
};
|
||||
static plMAXCameraLayerClassDesc plMAXCameraLayerDesc;
|
||||
ClassDesc2* GetMAXCameraLayerDesc() { return &plMAXCameraLayerDesc; }
|
||||
|
||||
class MAXCameraLayerDlgProc : public ParamMap2UserDlgProc
|
||||
{
|
||||
public:
|
||||
MAXCameraLayerDlgProc() {}
|
||||
~MAXCameraLayerDlgProc() {}
|
||||
|
||||
void UpdateDisplay(IParamMap2 *pmap)
|
||||
{
|
||||
HWND hWnd = pmap->GetHWnd();
|
||||
IParamBlock2 *pb = pmap->GetParamBlock();
|
||||
HWND cbox;
|
||||
cbox = GetDlgItem(hWnd, IDC_CAM_LAYER_UV_SRC);
|
||||
SendMessage(cbox, CB_SETCURSEL, pb->GetInt(plMAXCameraLayer::kUVSource), 0);
|
||||
hsBool reflect = (pb->GetInt(ParamID(plMAXCameraLayer::kExplicitCam)) == 0);
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_CAM_LAYER_UV_SRC), !reflect);
|
||||
}
|
||||
|
||||
virtual void Update(TimeValue t, Interval& valid, IParamMap2* pmap) { UpdateDisplay(pmap); }
|
||||
|
||||
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int id = LOWORD(wParam);
|
||||
int code = HIWORD(wParam);
|
||||
|
||||
IParamBlock2 *pb = map->GetParamBlock();
|
||||
HWND cbox = NULL;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
int i;
|
||||
for (i = 0; i < plMAXCameraLayer::kMaxUVSrc; i++)
|
||||
{
|
||||
cbox = GetDlgItem(hWnd, IDC_CAM_LAYER_UV_SRC);
|
||||
SendMessage(cbox, CB_ADDSTRING, 0, (LPARAM)plMAXCameraLayer::kUVStrings[i]);
|
||||
}
|
||||
UpdateDisplay(map);
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
if (id == IDC_CAM_LAYER_UV_SRC)
|
||||
{
|
||||
pb->SetValue(plMAXCameraLayer::kUVSource, t, SendMessage(GetDlgItem(hWnd, id), CB_GETCURSEL, 0, 0));
|
||||
return TRUE;
|
||||
}
|
||||
else if (id == IDC_CAM_LAYER_EXPLICIT_CAM)
|
||||
{
|
||||
UpdateDisplay(map);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
void DeleteThis() {}
|
||||
};
|
||||
static MAXCameraLayerDlgProc gMAXCameraLayerDlgProc;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// ParamBlock Definition ////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static ParamBlockDesc2 gMAXCameraLayerParamBlk
|
||||
(
|
||||
plMAXCameraLayer::kBlkMain, _T("CamLayer"), 0, GetMAXCameraLayerDesc(),
|
||||
P_AUTO_CONSTRUCT + P_AUTO_UI, plMAXCameraLayer::kRefMain,
|
||||
IDD_MAX_CAMERA_LAYER, IDS_MAX_CAMERA_LAYER_PROPS, 0, 0, &gMAXCameraLayerDlgProc,
|
||||
|
||||
plMAXCameraLayer::kCamera, _T("camera"), TYPE_INODE, P_CAN_CONVERT, 0,
|
||||
p_ui, TYPE_PICKNODEBUTTON, IDC_CAM_LAYER_CAMERA,
|
||||
p_classID, Class_ID(LOOKAT_CAM_CLASS_ID, 0),
|
||||
p_prompt, IDS_CAM_LAYER_CAMERA,
|
||||
end,
|
||||
|
||||
plMAXCameraLayer::kUVSource, _T("UVSource"), TYPE_INT, 0, 0,
|
||||
p_default, 0,
|
||||
end,
|
||||
|
||||
plMAXCameraLayer::kExplicitCam, _T("explicitCam"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_CAM_LAYER_EXPLICIT_CAM,
|
||||
p_default, false,
|
||||
p_enable_ctrls, 1, plMAXCameraLayer::kCamera,
|
||||
end,
|
||||
|
||||
plMAXCameraLayer::kRootNode, _T("rootNode"), TYPE_INODE, 0, 0,
|
||||
p_ui, TYPE_PICKNODEBUTTON, IDC_CAM_LAYER_ROOT_NODE,
|
||||
p_prompt, IDS_CAM_LAYER_ROOT_NODE,
|
||||
end,
|
||||
|
||||
plMAXCameraLayer::kDisableColor, _T("disableColor"), TYPE_RGBA, 0, 0,
|
||||
p_ui, TYPE_COLORSWATCH, IDC_CAM_LAYER_DISABLE_COLOR,
|
||||
p_default, Color(0,0,0),
|
||||
end,
|
||||
|
||||
plMAXCameraLayer::kForce, _T("force"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_CAM_LAYER_FORCE,
|
||||
p_default, false,
|
||||
end,
|
||||
|
||||
end
|
||||
);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char *plMAXCameraLayer::kUVStrings[] = { "1", "2", "3", "4", "5", "6", "7", "8" };
|
||||
const UInt8 plMAXCameraLayer::kMaxUVSrc = 8;
|
||||
|
||||
plMAXCameraLayer::plMAXCameraLayer() :
|
||||
fParmsPB(NULL),
|
||||
fIValid(NEVER)
|
||||
{
|
||||
plMAXCameraLayerDesc.MakeAutoParamBlocks(this);
|
||||
}
|
||||
|
||||
plMAXCameraLayer::~plMAXCameraLayer()
|
||||
{
|
||||
}
|
||||
|
||||
//From MtlBase
|
||||
void plMAXCameraLayer::Reset()
|
||||
{
|
||||
GetMAXCameraLayerDesc()->Reset(this, TRUE); // reset all pb2's
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
|
||||
|
||||
fIValid.SetEmpty();
|
||||
}
|
||||
|
||||
void plMAXCameraLayer::Update(TimeValue t, Interval& valid)
|
||||
{
|
||||
if (!fIValid.InInterval(t))
|
||||
{
|
||||
fIValid.SetInfinite();
|
||||
}
|
||||
|
||||
valid &= fIValid;
|
||||
}
|
||||
|
||||
Interval plMAXCameraLayer::Validity(TimeValue t)
|
||||
{
|
||||
Interval v = FOREVER;
|
||||
return v;
|
||||
}
|
||||
|
||||
ParamDlg* plMAXCameraLayer::CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp)
|
||||
{
|
||||
IAutoMParamDlg* masterDlg = plMAXCameraLayerDesc.CreateParamDlgs(hwMtlEdit, imp, this);
|
||||
|
||||
return masterDlg;
|
||||
}
|
||||
|
||||
BOOL plMAXCameraLayer::SetDlgThing(ParamDlg* dlg)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int plMAXCameraLayer::NumRefs()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
//From ReferenceMaker
|
||||
RefTargetHandle plMAXCameraLayer::GetReference(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case kRefMain: return fParmsPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void plMAXCameraLayer::SetReference(int i, RefTargetHandle rtarg)
|
||||
{
|
||||
Interval garbage;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case kRefMain:
|
||||
fParmsPB = (IParamBlock2 *)rtarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int plMAXCameraLayer::NumParamBlocks()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
IParamBlock2* plMAXCameraLayer::GetParamBlock(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: return fParmsPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IParamBlock2* plMAXCameraLayer::GetParamBlockByID(BlockID id)
|
||||
{
|
||||
if (fParmsPB->ID() == id)
|
||||
return fParmsPB;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//From ReferenceTarget
|
||||
RefTargetHandle plMAXCameraLayer::Clone(RemapDir &remap)
|
||||
{
|
||||
plMAXCameraLayer *mnew = TRACKED_NEW plMAXCameraLayer();
|
||||
*((MtlBase*)mnew) = *((MtlBase*)this); // copy superclass stuff
|
||||
mnew->ReplaceReference(kRefMain, remap.CloneRef(fParmsPB));
|
||||
BaseClone(this, mnew, remap);
|
||||
return (RefTargetHandle)mnew;
|
||||
}
|
||||
|
||||
int plMAXCameraLayer::NumSubs()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Animatable* plMAXCameraLayer::SubAnim(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case kRefMain: return fParmsPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TSTR plMAXCameraLayer::SubAnimName(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case kRefMain: return "Main";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
RefResult plMAXCameraLayer::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case REFMSG_CHANGE:
|
||||
{
|
||||
fIValid.SetEmpty();
|
||||
|
||||
if (hTarget == fParmsPB)
|
||||
{
|
||||
// see if this message came from a changing parameter in the pblock,
|
||||
// if so, limit rollout update to the changing item
|
||||
ParamID changingParam = fParmsPB->LastNotifyParamID();
|
||||
fParmsPB->GetDesc()->InvalidateUI(changingParam);
|
||||
|
||||
if (changingParam != -1)
|
||||
IChanged();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return REF_SUCCEED;
|
||||
}
|
||||
|
||||
void plMAXCameraLayer::IChanged()
|
||||
{
|
||||
// Cut and paste insanity from DynamicTextLayer.
|
||||
// Texture wasn't getting updated in the viewports, and this fixes it.
|
||||
// Don't know if it's the right way though.
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
|
||||
|
||||
// And this is so the SceneWatcher gets notified that the material on some of it's
|
||||
// referenced objects changed.
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_USER_MAT);
|
||||
}
|
||||
|
||||
#define TEX_HDR_CHUNK 0x5000
|
||||
|
||||
IOResult plMAXCameraLayer::Save(ISave *isave)
|
||||
{
|
||||
IOResult res;
|
||||
|
||||
isave->BeginChunk(TEX_HDR_CHUNK);
|
||||
res = MtlBase::Save(isave);
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
isave->EndChunk();
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult plMAXCameraLayer::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
if (iload->CurChunkID() == TEX_HDR_CHUNK)
|
||||
{
|
||||
res = MtlBase::Load(iload);
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
|
||||
AColor plMAXCameraLayer::EvalColor(ShadeContext& sc)
|
||||
{
|
||||
return AColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
float plMAXCameraLayer::EvalMono(ShadeContext& sc)
|
||||
{
|
||||
return Intens(EvalColor(sc));
|
||||
}
|
||||
|
||||
Point3 plMAXCameraLayer::EvalNormalPerturb(ShadeContext& sc)
|
||||
{
|
||||
// Return the perturbation to apply to a normal for bump mapping
|
||||
return Point3(0, 0, 0);
|
||||
}
|
||||
|
||||
ULONG plMAXCameraLayer::LocalRequirements(int subMtlNum)
|
||||
{
|
||||
return MTLREQ_VIEW_DEP | MTLREQ_TRANSP;
|
||||
}
|
||||
|
||||
void plMAXCameraLayer::ActivateTexDisplay(BOOL onoff)
|
||||
{
|
||||
}
|
||||
|
||||
BITMAPINFO *plMAXCameraLayer::GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono, BOOL forceW, BOOL forceH)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
DWORD plMAXCameraLayer::GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *plMAXCameraLayer::GetTextureName( int which )
|
||||
{
|
||||
return NULL;
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
#ifndef plMAXCameraLayer_inc
|
||||
#define plMAXCameraLayer_inc
|
||||
|
||||
#include "Max.h"
|
||||
#include "../resource.h"
|
||||
#include "plPlasmaMAXLayer.h"
|
||||
|
||||
class ClassDesc2;
|
||||
class IParamBlock2;
|
||||
|
||||
ClassDesc2* GetMAXCameraLayerDesc();
|
||||
|
||||
extern TCHAR *GetString(int id);
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
class plMAXCameraLayer : public plPlasmaMAXLayer
|
||||
{
|
||||
protected:
|
||||
// Parameter block
|
||||
IParamBlock2* fParmsPB;
|
||||
Interval fIValid;
|
||||
|
||||
public:
|
||||
// Ref nums
|
||||
enum
|
||||
{
|
||||
kRefMain
|
||||
};
|
||||
|
||||
// Block ID's
|
||||
enum
|
||||
{
|
||||
kBlkMain
|
||||
};
|
||||
|
||||
plMAXCameraLayer();
|
||||
~plMAXCameraLayer();
|
||||
void DeleteThis() { delete this; }
|
||||
|
||||
//From MtlBase
|
||||
ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
|
||||
BOOL SetDlgThing(ParamDlg* dlg);
|
||||
void Update(TimeValue t, Interval& valid);
|
||||
void Reset();
|
||||
Interval Validity(TimeValue t);
|
||||
ULONG LocalRequirements(int subMtlNum);
|
||||
|
||||
//From Texmap
|
||||
RGBA EvalColor(ShadeContext& sc);
|
||||
float EvalMono(ShadeContext& sc);
|
||||
Point3 EvalNormalPerturb(ShadeContext& sc);
|
||||
|
||||
// For displaying textures in the viewport
|
||||
BOOL SupportTexDisplay() { return FALSE; }
|
||||
void ActivateTexDisplay(BOOL onoff);
|
||||
BITMAPINFO *GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono=FALSE, int forceW=0, int forceH=0);
|
||||
DWORD GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
|
||||
|
||||
protected:
|
||||
void ICacheCosines();
|
||||
void IChanged();
|
||||
void IDiscardTexHandle();
|
||||
|
||||
public:
|
||||
|
||||
int SubNumToRefNum(int subNum) { return subNum; }
|
||||
virtual BOOL DiscardColor() { return true; }
|
||||
|
||||
// Loading/Saving
|
||||
IOResult Load(ILoad *iload);
|
||||
IOResult Save(ISave *isave);
|
||||
|
||||
//From Animatable
|
||||
Class_ID ClassID() { return MAX_CAMERA_LAYER_CLASS_ID; }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
void GetClassName(TSTR& s) { s = GetString(IDS_MAX_CAMERA_LAYER); }
|
||||
|
||||
RefTargetHandle Clone( RemapDir &remap );
|
||||
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message);
|
||||
|
||||
int NumSubs();
|
||||
Animatable* SubAnim(int i);
|
||||
TSTR SubAnimName(int i);
|
||||
|
||||
int NumRefs();
|
||||
RefTargetHandle GetReference(int i);
|
||||
void SetReference(int i, RefTargetHandle rtarg);
|
||||
|
||||
int NumParamBlocks(); // return number of ParamBlocks in this instance
|
||||
IParamBlock2* GetParamBlock(int i); // return i'th ParamBlock
|
||||
IParamBlock2* GetParamBlockByID(BlockID id); // return id'd ParamBlock
|
||||
|
||||
const char *GetTextureName( int which );
|
||||
|
||||
// ParamBlock accessors
|
||||
enum
|
||||
{
|
||||
kCamera,
|
||||
kUVSource,
|
||||
kExplicitCam,
|
||||
kRootNode,
|
||||
kDisableColor,
|
||||
kForce,
|
||||
};
|
||||
|
||||
static const char *kUVStrings[];
|
||||
static const UInt8 kMaxUVSrc;
|
||||
|
||||
// Pure virtual accessors for the various bitmap related elements
|
||||
virtual Bitmap *GetMaxBitmap(int index = 0) { hsAssert(false, "Function call not valid on this type of layer."); return nil; }
|
||||
virtual PBBitmap *GetPBBitmap(int index = 0) { hsAssert(false, "Function call not valid on this type of layer."); return nil; }
|
||||
virtual int GetNumBitmaps(void) { return 0; }
|
||||
|
||||
protected:
|
||||
virtual void ISetMaxBitmap(Bitmap *bitmap, int index = 0) { hsAssert(false, "Function call not valid on this type of layer."); }
|
||||
virtual void ISetPBBitmap(PBBitmap *pbbm, int index = 0) { hsAssert(false, "Function call not valid on this type of layer."); }
|
||||
};
|
||||
|
||||
#endif // plMAXCameraLayer_inc
|
@ -0,0 +1,442 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plPlasmaMAXLayer - MAX Layer type that is the basis for all Plasma layer //
|
||||
// types //
|
||||
// Note: All export-side functions are contained in //
|
||||
// MaxConvert/plPlasmaMaxLayerExport.cpp, for linking purposes. //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 1.13.2002 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plPlasmaMAXLayer.h"
|
||||
|
||||
#include "stdmat.h"
|
||||
#include "istdplug.h"
|
||||
#include "iparamb2.h"
|
||||
#include "iparamm2.h"
|
||||
#include "resource.h"
|
||||
#include "../../AssetMan/PublicInterface/MaxAssInterface.h"
|
||||
|
||||
#include "hsUtils.h"
|
||||
#include "../pnKeyedObject/hsKeyedObject.h"
|
||||
#include "../pnMessage/plRefMsg.h"
|
||||
#include "../plSurface/plLayerInterface.h"
|
||||
#include "hsResMgr.h"
|
||||
|
||||
|
||||
//// Derived Types List ///////////////////////////////////////////////////////
|
||||
// If you create a new Plasma layer type, add a define for the class ID in
|
||||
// the header and add it to the list here.
|
||||
|
||||
const Class_ID plPlasmaMAXLayer::fDerivedTypes[] =
|
||||
{
|
||||
LAYER_TEX_CLASS_ID,
|
||||
STATIC_ENV_LAYER_CLASS_ID,
|
||||
DYNAMIC_ENV_LAYER_CLASS_ID,
|
||||
DYN_TEXT_LAYER_CLASS_ID,
|
||||
ANGLE_ATTEN_LAYER_CLASS_ID,
|
||||
MAX_CAMERA_LAYER_CLASS_ID
|
||||
};
|
||||
|
||||
//// Constructor/Destructor ///////////////////////////////////////////////////
|
||||
|
||||
plPlasmaMAXLayer::plPlasmaMAXLayer()
|
||||
{
|
||||
fConversionTargets = nil;
|
||||
}
|
||||
|
||||
plPlasmaMAXLayer::~plPlasmaMAXLayer()
|
||||
{
|
||||
}
|
||||
|
||||
//// GetPlasmaMAXLayer ////////////////////////////////////////////////////////
|
||||
// Static function that checks the classID of the given texMap and, if it's a
|
||||
// valid Plasma MAX Layer, returns a pointer to such.
|
||||
|
||||
plPlasmaMAXLayer *plPlasmaMAXLayer::GetPlasmaMAXLayer( Texmap *map )
|
||||
{
|
||||
if (!map)
|
||||
return NULL;
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
for( i = 0; i < sizeof( fDerivedTypes ) / sizeof( Class_ID ); i++ )
|
||||
{
|
||||
if( map->ClassID() == fDerivedTypes[ i ] )
|
||||
return (plPlasmaMAXLayer *)map;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// Conversion Targets ///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// plLayerTargetContainer ///////////////////////////////////////////////////
|
||||
// This is a helper class that just contains a passive ref list of the layers
|
||||
// that are our conversion targets at export time. See, it's possible that a
|
||||
// layer gets converted, added to the target list, then destroyed as the
|
||||
// parent material is suddenly thrown away. In order to avoid our pointers
|
||||
// from being trashed (or keeping active refs on the layers when they're not
|
||||
// actually used), we have a small helper class that just keep passive refs,
|
||||
// so when one of them goes away, we get a notify about it.
|
||||
|
||||
class plLayerTargetContainer : public hsKeyedObject
|
||||
{
|
||||
static UInt32 fKeyCount;
|
||||
|
||||
public:
|
||||
hsTArray<plLayerInterface *> fLayers;
|
||||
|
||||
virtual hsBool MsgReceive( plMessage *msg )
|
||||
{
|
||||
plGenRefMsg *ref = plGenRefMsg::ConvertNoRef( msg );
|
||||
if( ref != nil )
|
||||
{
|
||||
if( ref->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
|
||||
fLayers[ ref->fWhich ] = plLayerInterface::ConvertNoRef( ref->GetRef() );
|
||||
else
|
||||
fLayers[ ref->fWhich ] = nil;
|
||||
}
|
||||
|
||||
return hsKeyedObject::MsgReceive( msg );
|
||||
}
|
||||
|
||||
plLayerTargetContainer()
|
||||
{
|
||||
char str[ 512 ];
|
||||
|
||||
|
||||
sprintf( str, "plLayerTargetContainer-%d", fKeyCount++ );
|
||||
hsgResMgr::ResMgr()->NewKey( str, this, plLocation::kGlobalFixedLoc );
|
||||
}
|
||||
};
|
||||
|
||||
UInt32 plLayerTargetContainer::fKeyCount = 0;
|
||||
|
||||
|
||||
void plPlasmaMAXLayer::IAddConversionTarget( plLayerInterface *target )
|
||||
{
|
||||
if( fConversionTargets == nil )
|
||||
{
|
||||
// Create us a new container
|
||||
fConversionTargets = TRACKED_NEW plLayerTargetContainer;
|
||||
fConversionTargets->GetKey()->RefObject();
|
||||
}
|
||||
|
||||
fConversionTargets->fLayers.Append( target );
|
||||
hsgResMgr::ResMgr()->AddViaNotify( target->GetKey(),
|
||||
new plGenRefMsg( fConversionTargets->GetKey(), plRefMsg::kOnCreate,
|
||||
fConversionTargets->fLayers.GetCount() - 1, 0 ),
|
||||
plRefFlags::kPassiveRef );
|
||||
}
|
||||
|
||||
void plPlasmaMAXLayer::IClearConversionTargets( void )
|
||||
{
|
||||
if( fConversionTargets != nil )
|
||||
{
|
||||
fConversionTargets->GetKey()->UnRefObject();
|
||||
fConversionTargets = nil;
|
||||
}
|
||||
}
|
||||
|
||||
int plPlasmaMAXLayer::GetNumConversionTargets( void )
|
||||
{
|
||||
if( fConversionTargets == nil )
|
||||
return 0;
|
||||
|
||||
|
||||
int i, count = 0;
|
||||
for( i = 0; i < fConversionTargets->fLayers.GetCount(); i++ )
|
||||
{
|
||||
if( fConversionTargets->fLayers[ i ] != nil )
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
plLayerInterface *plPlasmaMAXLayer::GetConversionTarget( int index )
|
||||
{
|
||||
if( fConversionTargets == nil )
|
||||
return nil;
|
||||
|
||||
int i;
|
||||
for( i = 0; i < fConversionTargets->fLayers.GetCount(); i++ )
|
||||
{
|
||||
if( fConversionTargets->fLayers[ i ] != nil )
|
||||
{
|
||||
if( index == 0 )
|
||||
return fConversionTargets->fLayers[ i ];
|
||||
index--;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// Asset Management, and textures ///////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plPlasmaMAXLayer::SetBitmapAssetId(jvUniqueId& assetId, int index /* = 0 */)
|
||||
{
|
||||
PBBitmap *pbbm = GetPBBitmap(index);
|
||||
if (pbbm && GetMaxAssInterface())
|
||||
{
|
||||
char buf[20];
|
||||
GetMaxAssInterface()->UniqueIdToString(assetId, buf);
|
||||
pbbm->bi.SetDevice(buf);
|
||||
}
|
||||
}
|
||||
|
||||
void plPlasmaMAXLayer::GetBitmapAssetId(jvUniqueId& assetId, int index /* = 0 */)
|
||||
{
|
||||
PBBitmap *pbbm = GetPBBitmap(index);
|
||||
if (pbbm && GetMaxAssInterface())
|
||||
assetId = GetMaxAssInterface()->StringToUniqueId(pbbm->bi.Device());
|
||||
else
|
||||
assetId.SetEmpty();
|
||||
}
|
||||
|
||||
void plPlasmaMAXLayer::SetBitmap(BitmapInfo *bi, int index)
|
||||
{
|
||||
jvUniqueId targetAssetId;
|
||||
GetBitmapAssetId(targetAssetId, index);
|
||||
|
||||
Bitmap *BM = GetMaxBitmap(index);
|
||||
if (BM)
|
||||
{
|
||||
BM->DeleteThis();
|
||||
BM = NULL;
|
||||
}
|
||||
|
||||
if (bi)
|
||||
{
|
||||
if (!targetAssetId.IsEmpty())
|
||||
{
|
||||
// If this texture has an assetId, we will check the
|
||||
// asset database and make sure we have the latest version
|
||||
// of the texture file before loading it
|
||||
MaxAssInterface* assInterface = GetMaxAssInterface();
|
||||
if (assInterface)
|
||||
{
|
||||
char buf[20];
|
||||
assInterface->UniqueIdToString(targetAssetId, buf);
|
||||
bi->SetDevice(buf);
|
||||
|
||||
const char* filename = bi->Name();
|
||||
// Download the latest version and retrieve the filename
|
||||
char newfilename[MAX_PATH];
|
||||
if (assInterface->GetLatestVersionFile(targetAssetId, newfilename, sizeof(newfilename)))
|
||||
{
|
||||
// If the filename has changed, we have to reset the bitmap in the ParamBlock
|
||||
if(stricmp(filename, newfilename) != 0)
|
||||
bi->SetName(newfilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BMMRES result;
|
||||
BM = TheManager->Load(bi, &result);
|
||||
if (result == BMMRES_SUCCESS)
|
||||
ISetMaxBitmap(BM, index);
|
||||
else
|
||||
ISetMaxBitmap(NULL, index);
|
||||
|
||||
// The load may have failed, but we still want to set the paramblock. We
|
||||
// don't want to modify the layer if we're just missing the file.
|
||||
PBBitmap pbBitmap(*bi);
|
||||
ISetPBBitmap(&pbBitmap, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
ISetMaxBitmap(NULL, index);
|
||||
ISetPBBitmap(NULL, index);
|
||||
}
|
||||
|
||||
/*
|
||||
Bitmap *BM = GetMaxBitmap(index);
|
||||
|
||||
if (BM)
|
||||
{
|
||||
BM->DeleteThis();
|
||||
BM = NULL;
|
||||
}
|
||||
|
||||
if (filename)
|
||||
{
|
||||
BitmapInfo bi;
|
||||
bi.SetName(filename);
|
||||
|
||||
// If this texture has an assetId, get the latest version from AssetMan before loading it
|
||||
if (assetId && !assetId->IsEmpty())
|
||||
{
|
||||
MaxAssInterface* maxAssInterface = GetMaxAssInterface();
|
||||
if (maxAssInterface)
|
||||
{
|
||||
// Download the latest version and retrieve the filename
|
||||
char newfilename[MAX_PATH];
|
||||
if (maxAssInterface->GetLatestVersionFile(*assetId, newfilename, sizeof(newfilename)))
|
||||
{
|
||||
// If the filename has changed, we have to reset the bitmap in the ParamBlock
|
||||
if (stricmp(filename, newfilename) != 0)
|
||||
{
|
||||
bi.SetName(newfilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ISetMaxBitmap(TheManager->Load(&bi));
|
||||
|
||||
PBBitmap pbBitmap(bi);
|
||||
// TheManager->LoadInto(&pbBitmap.bi, &pbBitmap.bm, TRUE);
|
||||
ISetPBBitmap(&pbBitmap, index);
|
||||
|
||||
if (assetId)
|
||||
SetBitmapAssetId(*assetId, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
ISetMaxBitmap(NULL, index);
|
||||
ISetPBBitmap(NULL, index);
|
||||
}
|
||||
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
|
||||
*/
|
||||
}
|
||||
|
||||
//// RefreshBitmaps ///////////////////////////////////////////////////////////
|
||||
// Makes sure the bitmap asset is the latest from AssetMan, if we're using it.
|
||||
|
||||
void plPlasmaMAXLayer::RefreshBitmaps()
|
||||
{
|
||||
int i, count = GetNumBitmaps();
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
PBBitmap *pbbm = GetPBBitmap(i);
|
||||
if (pbbm)
|
||||
{
|
||||
SetBitmap(&pbbm->bi, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//// GetBitmapFileName ////////////////////////////////////////////////////////
|
||||
// Returns the filename of the ith bitmap. Makes sure we have the latest
|
||||
// version from assetMan as well, if applicable.
|
||||
|
||||
hsBool plPlasmaMAXLayer::GetBitmapFileName( char *destFilename, int maxLength, int index /* = 0 */ )
|
||||
{
|
||||
jvUniqueId targetAssetId;
|
||||
GetBitmapAssetId(targetAssetId, index);
|
||||
|
||||
MaxAssInterface* maxAssInterface = GetMaxAssInterface();
|
||||
if (maxAssInterface != nil && !targetAssetId.IsEmpty())
|
||||
{
|
||||
// Download the latest version and retrieve the filename
|
||||
if (maxAssInterface->GetLatestVersionFile(targetAssetId, destFilename, maxLength))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Normal return
|
||||
if( GetPBBitmap( index ) == nil )
|
||||
return false;
|
||||
|
||||
strncpy( destFilename, GetPBBitmap( index )->bi.Name(), maxLength );
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL plPlasmaMAXLayer::HandleBitmapSelection(int index /* = 0 */)
|
||||
{
|
||||
static ICustButton* bmSelectBtn;
|
||||
|
||||
PBBitmap *pbbm = GetPBBitmap( index );
|
||||
|
||||
MaxAssInterface* maxAssInterface = GetMaxAssInterface();
|
||||
|
||||
// If the control key is held, we want to get rid of this texture
|
||||
if ((GetKeyState(VK_CONTROL) & 0x8000) && pbbm != nil)
|
||||
{
|
||||
char msg[512];
|
||||
sprintf(msg, "Are you sure you want to change this bitmap from %s to (none)?", pbbm->bi.Name());
|
||||
if (hsMessageBox(msg, "Remove texture?", hsMessageBoxYesNo) == hsMBoxYes)
|
||||
{
|
||||
SetBitmap(nil, index);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
// if we have the assetman plug-in, then try to use it, unless shift is held down
|
||||
else if(maxAssInterface && !(GetKeyState(VK_SHIFT) & 0x8000))
|
||||
{
|
||||
jvUniqueId assetId;
|
||||
GetBitmapAssetId(assetId, index);
|
||||
|
||||
char filename[MAX_PATH];
|
||||
if (maxAssInterface->OpenBitmapDlg(assetId, filename, sizeof(filename)))
|
||||
{
|
||||
SetBitmapAssetId(assetId, index);
|
||||
|
||||
BitmapInfo bi;
|
||||
bi.SetName(filename);
|
||||
SetBitmap(&bi, index);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BitmapInfo bi;
|
||||
if( pbbm != NULL )
|
||||
bi.SetName( pbbm->bi.Name() );
|
||||
|
||||
BOOL selectedNewBitmap = TheManager->SelectFileInput(&bi,
|
||||
GetCOREInterface()->GetMAXHWnd(),
|
||||
_T("Select Bitmap Image File"));
|
||||
|
||||
if (selectedNewBitmap)
|
||||
{
|
||||
// Set the assetId to empty so our new, unmanaged texture will take
|
||||
jvUniqueId emptyId;
|
||||
SetBitmapAssetId(emptyId, index);
|
||||
|
||||
SetBitmap(&bi, index);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plPlasmaMAXLayer - MAX Layer type that is the basis for all Plasma layer //
|
||||
// types //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 1.13.2002 mcn - Created. //
|
||||
// //
|
||||
//// Notes from the Author ////////////////////////////////////////////////////
|
||||
// //
|
||||
// This base class is actually a quite-recent addition. As a result, most //
|
||||
// of the old, non-base-class-structured code is still lying around. This //
|
||||
// code will be slowly converted over as time goes on; the theory was that //
|
||||
// this conversion would be far more likely to occur if the base class //
|
||||
// actually already existed. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plPlasmaMAXLayer_h
|
||||
#define _plPlasmaMAXLayer_h
|
||||
|
||||
#include "Max.h"
|
||||
#include "hsTypes.h"
|
||||
|
||||
//// Derived Type Class IDs ///////////////////////////////////////////////////
|
||||
// If you create a new Plasma layer type, add a define for the class ID here
|
||||
// and also add the ID to the list in plPlasmaMAXLayer.cpp.
|
||||
|
||||
const Class_ID LAYER_TEX_CLASS_ID( 0x4223c620, 0x183c4868 );
|
||||
const Class_ID STATIC_ENV_LAYER_CLASS_ID( 0x379a0a20, 0x3d0b1244 );
|
||||
const Class_ID DYNAMIC_ENV_LAYER_CLASS_ID( 0x18205c0f, 0x57ea0e10 );
|
||||
const Class_ID DYN_TEXT_LAYER_CLASS_ID( 0x36e3480f, 0x120120bd );
|
||||
const Class_ID ANGLE_ATTEN_LAYER_CLASS_ID( 0x6d90918, 0x6160114 );
|
||||
const Class_ID MAX_CAMERA_LAYER_CLASS_ID( 0xfaf5ec7, 0x13d90d3f );
|
||||
|
||||
//// Class Definition /////////////////////////////////////////////////////////
|
||||
|
||||
class plLayerInterface;
|
||||
class plMaxNode;
|
||||
class plErrorMsg;
|
||||
class plLayer;
|
||||
class plDynamicTextMap;
|
||||
class plBitmapData;
|
||||
class plLocation;
|
||||
class plLayerConverter;
|
||||
class plLayerInterface;
|
||||
class plBMSamplerData;
|
||||
class jvUniqueId;
|
||||
class plLayerTargetContainer;
|
||||
class plPlasmaMAXLayer : public Texmap
|
||||
{
|
||||
friend class plLayerConverter;
|
||||
|
||||
protected:
|
||||
|
||||
static const Class_ID fDerivedTypes[];
|
||||
|
||||
plLayerTargetContainer *fConversionTargets;
|
||||
|
||||
|
||||
void IAddConversionTarget( plLayerInterface *target );
|
||||
void IClearConversionTargets( void );
|
||||
|
||||
public:
|
||||
|
||||
plPlasmaMAXLayer();
|
||||
virtual ~plPlasmaMAXLayer();
|
||||
|
||||
void DeleteThis() { delete this; }
|
||||
|
||||
|
||||
// Static that checks the classID of the given texMap and, if it's a valid Plasma MAX Layer, returns a pointer to such
|
||||
static plPlasmaMAXLayer *GetPlasmaMAXLayer( Texmap *map );
|
||||
|
||||
// Some layers must be unique for each node they're applied to (i.e. can't be shared among nodes).
|
||||
// This returns true if the layer must be unique.
|
||||
virtual bool MustBeUnique( void ) { return false; }
|
||||
|
||||
// These let the material make an informed decision on what to do with
|
||||
// the color and alpha values coming out of an EvalColor call. Something
|
||||
// like an InvertColor can be handled within EvalColor, but there needs
|
||||
// to be a way to tell the caller that the color returned should be completely
|
||||
// ignored.
|
||||
virtual BOOL DiscardColor() { return false; }
|
||||
virtual BOOL DiscardAlpha() { return false; }
|
||||
|
||||
|
||||
// Return the number of conversion targets (only valid after the MakeMesh pass)
|
||||
int GetNumConversionTargets( void );
|
||||
|
||||
// Get an indexed conversion target
|
||||
plLayerInterface *GetConversionTarget( int index );
|
||||
|
||||
virtual BOOL HandleBitmapSelection(int index = 0);
|
||||
virtual void SetBitmap(BitmapInfo *bi, int index = 0);
|
||||
virtual void SetBitmapAssetId(jvUniqueId& assetId, int index = 0);
|
||||
virtual void GetBitmapAssetId(jvUniqueId& assetId, int index = 0);
|
||||
|
||||
// Pure virtual accessors for the various bitmap related elements
|
||||
virtual Bitmap *GetMaxBitmap(int index = 0) = 0;
|
||||
virtual PBBitmap *GetPBBitmap( int index = 0 ) = 0;
|
||||
virtual int GetNumBitmaps( void ) = 0;
|
||||
|
||||
// Makes sure the textures are the latest versions (including getting
|
||||
// the latest version from AssetMan)
|
||||
void RefreshBitmaps();
|
||||
|
||||
hsBool GetBitmapFileName( char *destFilename, int maxLength, int index = 0 );
|
||||
|
||||
// Virtual function called by plBMSampler to get various things while sampling the layer's image
|
||||
virtual bool GetSamplerInfo( plBMSamplerData *samplerData ) { return false; }
|
||||
|
||||
// Backdoor for the texture find and replace util. Assumes input has the correct aspect ratio and is power of 2.
|
||||
virtual void SetExportSize(int x, int y) {}
|
||||
|
||||
protected:
|
||||
virtual void ISetMaxBitmap(Bitmap *bitmap, int index = 0) = 0;
|
||||
virtual void ISetPBBitmap( PBBitmap *pbbm, int index = 0 ) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif // _plPlasmaMAXLayer_h
|
@ -0,0 +1,696 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plStaticEnvLayer.h"
|
||||
|
||||
#include "iparamb2.h"
|
||||
#include "iparamm2.h"
|
||||
#include "stdmat.h"
|
||||
|
||||
#include "plBMSampler.h"
|
||||
#include "../MaxMain/plPlasmaRefMsgs.h"
|
||||
|
||||
class plStaticEnvLayerClassDesc : public ClassDesc2
|
||||
{
|
||||
public:
|
||||
int IsPublic() { return TRUE; }
|
||||
void* Create(BOOL loading = FALSE) { return TRACKED_NEW plStaticEnvLayer(); }
|
||||
const TCHAR* ClassName() { return GetString(IDS_STATIC_ENVMAP_LAYER); }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
Class_ID ClassID() { return STATIC_ENV_LAYER_CLASS_ID; }
|
||||
const TCHAR* Category() { return TEXMAP_CAT_ENV; }
|
||||
const TCHAR* InternalName() { return _T("PlasmaStaticEnvMapLayer"); }
|
||||
HINSTANCE HInstance() { return hInstance; }
|
||||
};
|
||||
static plStaticEnvLayerClassDesc plStaticEnvLayerDesc;
|
||||
ClassDesc2* GetStaticEnvLayerDesc() { return &plStaticEnvLayerDesc; }
|
||||
|
||||
#include "plStaticEnvLayerBitmapPB.cpp"
|
||||
|
||||
plStaticEnvLayer::plStaticEnvLayer() :
|
||||
fBitmapPB(NULL),
|
||||
fUVGen(NULL),
|
||||
fTexHandle(NULL),
|
||||
fTexTime(0),
|
||||
fIValid(NEVER)
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
fBitmaps[ i ] = NULL;
|
||||
}
|
||||
|
||||
plStaticEnvLayerDesc.MakeAutoParamBlocks(this);
|
||||
ReplaceReference(kRefUVGen, GetNewDefaultUVGen());
|
||||
}
|
||||
|
||||
plStaticEnvLayer::~plStaticEnvLayer()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
if( fBitmaps[ i ] )
|
||||
fBitmaps[ i ]->DeleteThis();
|
||||
}
|
||||
|
||||
IDiscardTexHandle();
|
||||
}
|
||||
|
||||
//From MtlBase
|
||||
void plStaticEnvLayer::Reset()
|
||||
{
|
||||
GetStaticEnvLayerDesc()->Reset(this, TRUE); // reset all pb2's
|
||||
for( int i = 0; i < 6; i++ )
|
||||
{
|
||||
SetBitmap( NULL, i );
|
||||
}
|
||||
|
||||
fIValid.SetEmpty();
|
||||
}
|
||||
|
||||
void plStaticEnvLayer::Update(TimeValue t, Interval& valid)
|
||||
{
|
||||
if (!fIValid.InInterval(t))
|
||||
{
|
||||
fIValid.SetInfinite();
|
||||
|
||||
fUVGen->Update(t,fIValid);
|
||||
fBitmapPB->GetValidity(t, fIValid);
|
||||
}
|
||||
|
||||
// Gonna need to do this when we support animated bm's
|
||||
#if 0
|
||||
if (fBM)
|
||||
{
|
||||
if (bi.FirstFrame()!=bi.LastFrame())
|
||||
ivalid.SetInstant(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
valid &= fIValid;
|
||||
}
|
||||
|
||||
Interval plStaticEnvLayer::Validity(TimeValue t)
|
||||
{
|
||||
//TODO: Update fIValid here
|
||||
|
||||
// mf horse - Hacking this in just to get animations working.
|
||||
// No warranty on this not being stupid.
|
||||
Interval v = FOREVER;
|
||||
fBitmapPB->GetValidity(t, v);
|
||||
v &= fUVGen->Validity(t);
|
||||
return v;
|
||||
}
|
||||
|
||||
ParamDlg* plStaticEnvLayer::CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp)
|
||||
{
|
||||
fIMtlParams = imp;
|
||||
IAutoMParamDlg* masterDlg = plStaticEnvLayerDesc.CreateParamDlgs(hwMtlEdit, imp, this);
|
||||
|
||||
SELBitmapDlgProc *paramDlg = (SELBitmapDlgProc *)gBitmapParamBlk.GetUserDlgProc();
|
||||
if( paramDlg )
|
||||
paramDlg->fMtlParams = imp;
|
||||
|
||||
return masterDlg;
|
||||
}
|
||||
|
||||
BOOL plStaticEnvLayer::SetDlgThing(ParamDlg* dlg)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int plStaticEnvLayer::NumRefs()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
//From ReferenceMaker
|
||||
RefTargetHandle plStaticEnvLayer::GetReference(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen: return fUVGen;
|
||||
case kRefBitmap: return fBitmapPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void plStaticEnvLayer::SetReference(int i, RefTargetHandle rtarg)
|
||||
{
|
||||
Interval garbage;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen:
|
||||
fUVGen = (UVGen *)rtarg;
|
||||
if( fUVGen )
|
||||
fUVGen->Update( TimeValue( 0 ), garbage );
|
||||
break;
|
||||
case kRefBitmap:
|
||||
fBitmapPB = (IParamBlock2 *)rtarg;
|
||||
// KLUDGE: If the paramblock is being set chances are we are being created or
|
||||
// loaded. In the case of load, we want to refresh our textures.
|
||||
if (fBitmapPB)
|
||||
RefreshBitmaps();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int plStaticEnvLayer::NumParamBlocks()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
IParamBlock2* plStaticEnvLayer::GetParamBlock(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: return fBitmapPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IParamBlock2* plStaticEnvLayer::GetParamBlockByID(BlockID id)
|
||||
{
|
||||
if (fBitmapPB->ID() == id)
|
||||
return fBitmapPB;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//From ReferenceTarget
|
||||
RefTargetHandle plStaticEnvLayer::Clone(RemapDir &remap)
|
||||
{
|
||||
plStaticEnvLayer *mnew = TRACKED_NEW plStaticEnvLayer();
|
||||
*((MtlBase*)mnew) = *((MtlBase*)this); // copy superclass stuff
|
||||
mnew->ReplaceReference(kRefBitmap, remap.CloneRef(fBitmapPB));
|
||||
mnew->ReplaceReference(kRefUVGen, remap.CloneRef(fUVGen));
|
||||
BaseClone(this, mnew, remap);
|
||||
return (RefTargetHandle)mnew;
|
||||
}
|
||||
|
||||
int plStaticEnvLayer::NumSubs()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
Animatable* plStaticEnvLayer::SubAnim(int i)
|
||||
{
|
||||
//TODO: Return 'i-th' sub-anim
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen: return fUVGen;
|
||||
case kRefBitmap: return fBitmapPB;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TSTR plStaticEnvLayer::SubAnimName(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case kRefUVGen: return "UVGen";
|
||||
case kRefBitmap: return fBitmapPB->GetLocalName();
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
RefResult plStaticEnvLayer::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case REFMSG_CHANGE:
|
||||
{
|
||||
fIValid.SetEmpty();
|
||||
|
||||
if (hTarget == fBitmapPB)
|
||||
{
|
||||
// see if this message came from a changing parameter in the pblock,
|
||||
// if so, limit rollout update to the changing item and update any active viewport texture
|
||||
ParamID changingParam = fBitmapPB->LastNotifyParamID();
|
||||
fBitmapPB->GetDesc()->InvalidateUI(changingParam);
|
||||
|
||||
if (changingParam != -1)
|
||||
IChanged();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case REFMSG_UV_SYM_CHANGE:
|
||||
IDiscardTexHandle();
|
||||
break;
|
||||
}
|
||||
|
||||
return REF_SUCCEED;
|
||||
}
|
||||
|
||||
void plStaticEnvLayer::IChanged()
|
||||
{
|
||||
IDiscardTexHandle();
|
||||
// Texture wasn't getting updated in the viewports, and this fixes it.
|
||||
// Don't know if it's the right way though.
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
|
||||
|
||||
// And this is so the SceneWatcher gets notified that the material on some of it's
|
||||
// referenced objects changed.
|
||||
NotifyDependents(FOREVER, PART_ALL, REFMSG_USER_MAT);
|
||||
}
|
||||
|
||||
#define TEX_HDR_CHUNK 0x5000
|
||||
#define MAX_ASS_CHUNK 0x5500
|
||||
|
||||
IOResult plStaticEnvLayer::Save(ISave *isave)
|
||||
{
|
||||
IOResult res;
|
||||
|
||||
isave->BeginChunk(TEX_HDR_CHUNK);
|
||||
res = MtlBase::Save(isave);
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
isave->EndChunk();
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult plStaticEnvLayer::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
if (iload->CurChunkID() == TEX_HDR_CHUNK)
|
||||
{
|
||||
res = MtlBase::Load(iload);
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
inline Point2 CompUV(float x, float y, float z)
|
||||
{
|
||||
return Point2( 0.5f * ( x / z + 1.0f ), 0.5f * ( y / z + 1.0f ) );
|
||||
}
|
||||
|
||||
AColor plStaticEnvLayer::EvalColor(ShadeContext& sc)
|
||||
{
|
||||
if (!sc.doMaps)
|
||||
return AColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
AColor color;
|
||||
if (sc.GetCache(this, color))
|
||||
return color;
|
||||
|
||||
if (gbufID)
|
||||
sc.SetGBufferID(gbufID);
|
||||
|
||||
// Evaluate the Bitmap
|
||||
|
||||
// Point3 v = sc.VectorTo( sc.V(), REF_OBJECT );//WORLD );
|
||||
Point3 v = sc.VectorTo( sc.Normal(), REF_OBJECT );
|
||||
float wx,wy,wz;
|
||||
Color rcol;
|
||||
Bitmap *refmap = NULL;
|
||||
Point3 rv;
|
||||
Point2 uv;
|
||||
int size;
|
||||
|
||||
wx = (float)fabs( v.x );
|
||||
wy = (float)fabs( v.y );
|
||||
wz = (float)fabs( v.z );
|
||||
if( wx >= wy && wx >= wz )
|
||||
{
|
||||
if( v.x < 0 )
|
||||
{
|
||||
refmap = fBitmaps[ kLeftFace ];
|
||||
uv = CompUV( -v.y, -v.z, v.x );
|
||||
}
|
||||
else
|
||||
{
|
||||
refmap = fBitmaps[ kRightFace ];
|
||||
uv = CompUV( v.y, -v.z, -v.x );
|
||||
}
|
||||
}
|
||||
else if( wy >= wx && wy >= wz )
|
||||
{
|
||||
if( v.y > 0 )
|
||||
{
|
||||
refmap = fBitmaps[ kBackFace ];
|
||||
uv = CompUV( -v.x, -v.z, -v.y );
|
||||
}
|
||||
else
|
||||
{
|
||||
refmap = fBitmaps[ kFrontFace ];
|
||||
uv = CompUV( v.x, -v.z, v.y );
|
||||
}
|
||||
}
|
||||
else if( wz >= wx && wz >= wy )
|
||||
{
|
||||
if( v.z < 0 )
|
||||
{
|
||||
refmap = fBitmaps[ kBottomFace ];
|
||||
uv = CompUV( -v.x, -v.y, v.z );
|
||||
}
|
||||
else
|
||||
{
|
||||
refmap = fBitmaps[ kTopFace ];
|
||||
uv = CompUV( -v.x, v.y, -v.z );
|
||||
}
|
||||
}
|
||||
|
||||
if( refmap == NULL )
|
||||
color.White();
|
||||
else
|
||||
{
|
||||
if( uv.x < 0.0f )
|
||||
uv.x = 0.0f;
|
||||
else if( uv.x > 1.0f )
|
||||
uv.x = 1.0f;
|
||||
if( uv.y < 0.0f )
|
||||
uv.y = 0.0f;
|
||||
else if( uv.y > 1.0f )
|
||||
uv.y = 1.0f;
|
||||
size = refmap->Width();
|
||||
int x = (int)( uv.x * (float)( size - 1 ) );
|
||||
int y = (int)( ( 1.0f - uv.y ) * (float)( size - 1 ) );
|
||||
|
||||
BMM_Color_64 c;
|
||||
refmap->GetLinearPixels( x, y, 1, &c );
|
||||
color = AColor( c.r / 65535.f, c.g / 65535.f, c.b / 65535.f, c.a / 65535.f );
|
||||
}
|
||||
|
||||
// Invert color if specified
|
||||
if( fBitmapPB->GetInt( kBmpInvertColor ) )
|
||||
{
|
||||
color.r = 1.0f - color.r;
|
||||
color.g = 1.0f - color.g;
|
||||
color.b = 1.0f - color.b;
|
||||
}
|
||||
// Discard color if specified
|
||||
if( fBitmapPB->GetInt( kBmpDiscardColor ) )
|
||||
color.r = color.g = color.b = 1.0f;
|
||||
|
||||
// Invert alpha if specified
|
||||
if( fBitmapPB->GetInt( kBmpInvertAlpha ) )
|
||||
color.a = 1.0f - color.a;
|
||||
// Discard alpha if specified
|
||||
if( fBitmapPB->GetInt( kBmpDiscardAlpha ) )
|
||||
color.a = 1.0f;
|
||||
|
||||
// If RGB output is set to alpha, show RGB as grayscale of the alpha
|
||||
if( fBitmapPB->GetInt( kBmpRGBOutput ) == 1 )
|
||||
color = AColor( color.a, color.a, color.a, 1.0f );
|
||||
|
||||
sc.PutCache(this, color);
|
||||
return color;
|
||||
}
|
||||
|
||||
float plStaticEnvLayer::EvalMono(ShadeContext& sc)
|
||||
{
|
||||
if (fBitmapPB->GetInt(kBmpMonoOutput) == 1)
|
||||
return EvalColor(sc).a;
|
||||
|
||||
return Intens(EvalColor(sc));
|
||||
}
|
||||
|
||||
Point3 plStaticEnvLayer::EvalNormalPerturb(ShadeContext& sc)
|
||||
{
|
||||
// Return the perturbation to apply to a normal for bump mapping
|
||||
return Point3(0, 0, 0);
|
||||
}
|
||||
|
||||
ULONG plStaticEnvLayer::LocalRequirements(int subMtlNum)
|
||||
{
|
||||
if( fBitmapPB->GetInt( kBmpUseMAXAtmosphere ) )
|
||||
return MTLREQ_VIEW_DEP;
|
||||
|
||||
return MTLREQ_VIEW_DEP | MTLREQ_NOATMOS;
|
||||
}
|
||||
|
||||
void plStaticEnvLayer::IDiscardTexHandle()
|
||||
{
|
||||
if (fTexHandle)
|
||||
{
|
||||
fTexHandle->DeleteThis();
|
||||
fTexHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void plStaticEnvLayer::ActivateTexDisplay(BOOL onoff)
|
||||
{
|
||||
if (!onoff)
|
||||
IDiscardTexHandle();
|
||||
}
|
||||
|
||||
BITMAPINFO *plStaticEnvLayer::GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono, BOOL forceW, BOOL forceH)
|
||||
{
|
||||
// FIXME
|
||||
fTexTime = 0;//CalcFrame(t);
|
||||
// texValid = clipValid;
|
||||
BITMAPINFO *bmi = NULL;
|
||||
int xflags = 0;
|
||||
|
||||
if (fBitmapPB->GetInt(kBmpRGBOutput) == 1)
|
||||
xflags |= EX_RGB_FROM_ALPHA;
|
||||
bmi = thmaker.BitmapToDIB(fBitmaps[ 0 ], fUVGen->SymFlags(), xflags, forceW, forceH);
|
||||
|
||||
return bmi;
|
||||
}
|
||||
|
||||
DWORD plStaticEnvLayer::GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker)
|
||||
{
|
||||
// FIXME: ignore validity for now
|
||||
if (fTexHandle && fIValid.InInterval(t))// && texTime == CalcFrame(t))
|
||||
return fTexHandle->GetHandle();
|
||||
else
|
||||
{
|
||||
IDiscardTexHandle();
|
||||
|
||||
fTexTime = 0;//CalcFrame(t);
|
||||
fTexHandle = thmaker.MakeHandle(GetVPDisplayDIB(t, thmaker, fIValid));
|
||||
if (fTexHandle)
|
||||
return fTexHandle->GetHandle();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char *plStaticEnvLayer::GetTextureName( int which )
|
||||
{
|
||||
// if (fBitmapPB->GetInt(kBmpUseBitmap))
|
||||
{
|
||||
PBBitmap *pbbm = fBitmapPB->GetBitmap( kBmpFrontBitmap + which );
|
||||
if (pbbm)
|
||||
return pbbm->bi.Name();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//// Set/GetBaseFilename //////////////////////////////////////////////////////
|
||||
|
||||
void plStaticEnvLayer::SetBaseFilename( const TCHAR *name, TimeValue t )
|
||||
{
|
||||
fBitmapPB->SetValue( kBmpBaseFilename, t, (TCHAR *)name );
|
||||
}
|
||||
|
||||
const TCHAR *plStaticEnvLayer::GetBaseFilename( TimeValue t )
|
||||
{
|
||||
Interval valid;
|
||||
TCHAR *buffer;
|
||||
|
||||
fBitmapPB->GetValue( kBmpBaseFilename, t, buffer, valid );
|
||||
return (const TCHAR *)buffer;
|
||||
}
|
||||
|
||||
//// IGetViewTM ///////////////////////////////////////////////////////////////
|
||||
|
||||
Matrix3 plStaticEnvLayer::IGetViewTM( int i )
|
||||
{
|
||||
Matrix3 m;
|
||||
m.IdentityMatrix();
|
||||
switch( i )
|
||||
{
|
||||
case kTopFace:
|
||||
m.RotateX( -PI );
|
||||
break;
|
||||
case kBottomFace:
|
||||
break;
|
||||
case kLeftFace:
|
||||
m.RotateX( -.5f * PI );
|
||||
m.RotateY( -.5f * PI );
|
||||
break;
|
||||
case kRightFace:
|
||||
m.RotateX( -.5f * PI );
|
||||
m.RotateY( +.5f * PI );
|
||||
break;
|
||||
case kFrontFace:
|
||||
m.RotateX( -.5f * PI );
|
||||
m.RotateY( PI );
|
||||
break;
|
||||
case kBackFace:
|
||||
m.RotateX( -.5f * PI );
|
||||
break;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
//// IWriteBM /////////////////////////////////////////////////////////////////
|
||||
|
||||
int plStaticEnvLayer::IWriteBM( BitmapInfo *bi, Bitmap *bm, TCHAR *name )
|
||||
{
|
||||
bi->SetName( name );
|
||||
if( bm->OpenOutput( bi ) == BMMRES_SUCCESS )
|
||||
{
|
||||
if( bm->Write( bi, BMM_SINGLEFRAME ) == BMMRES_SUCCESS )
|
||||
{
|
||||
bm->Close( bi );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//// RenderCubicMap ///////////////////////////////////////////////////////////
|
||||
// Generates the 6 faces for a cubic map based on a picked node
|
||||
|
||||
void plStaticEnvLayer::RenderCubicMap( INode *node )
|
||||
{
|
||||
int res, size;
|
||||
BOOL success = 0;
|
||||
TSTR fname, fullname;
|
||||
Bitmap *bm = NULL;
|
||||
TSTR path, filename, ext, thisFilename;
|
||||
BitmapInfo biOutFile;
|
||||
|
||||
static TCHAR suffixes[ 6 ][ 4 ] = { "_FR", "_BK", "_LF", "_RT", "_UP", "_DN" };
|
||||
|
||||
|
||||
Interface *ip = GetCOREInterface();
|
||||
size = fBitmapPB->GetInt( kBmpTextureSize, ip->GetTime() );
|
||||
if( size <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
thisFilename = fBitmapPB->GetStr( kBmpBaseFilename, ip->GetTime() );
|
||||
if( thisFilename.isNull() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SplitFilename( thisFilename, &path, &filename, &ext );
|
||||
|
||||
BOOL wasHid = node->IsNodeHidden();
|
||||
node->Hide( TRUE );
|
||||
|
||||
// Create a blank bitmap
|
||||
biOutFile.SetWidth( size );
|
||||
biOutFile.SetHeight( size );
|
||||
biOutFile.SetType( BMM_TRUE_64 );
|
||||
biOutFile.SetAspect( 1.0f );
|
||||
biOutFile.SetCurrentFrame( 0 );
|
||||
bm = TheManager->Create( &biOutFile );
|
||||
|
||||
Matrix3 nodeTM = node->GetNodeTM( ip->GetTime() );
|
||||
Matrix3 tm;
|
||||
INode *root = ip->GetRootNode();
|
||||
bm->Display( GetString( IDS_CUBIC_RENDER_TITLE ) );
|
||||
|
||||
/// Set up rendering contexts
|
||||
ViewParams vp;
|
||||
vp.projType = PROJ_PERSPECTIVE;
|
||||
vp.hither = .001f;
|
||||
vp.yon = 1.0e30f;
|
||||
vp.fov = PI/2.0f;
|
||||
if( fBitmapPB->GetInt( kBmpUseMAXAtmosphere ) )
|
||||
{
|
||||
vp.nearRange = 0;
|
||||
vp.farRange = fBitmapPB->GetFloat( kBmpFarDistance );
|
||||
}
|
||||
else
|
||||
{
|
||||
vp.nearRange = vp.farRange = 1.0e30f;
|
||||
}
|
||||
BOOL saveUseEnvMap = ip->GetUseEnvironmentMap();
|
||||
ip->SetUseEnvironmentMap( false );
|
||||
|
||||
res = ip->OpenCurRenderer( &vp );
|
||||
for( int i = 0; i < 6; i++ )
|
||||
{
|
||||
tm = IGetViewTM( i );
|
||||
tm.PreTranslate( -nodeTM.GetTrans() );
|
||||
vp.affineTM = tm;
|
||||
|
||||
// Construct filename
|
||||
thisFilename.printf( _T( "%s\\%s%s%s" ), path, filename, suffixes[ i ], ext );
|
||||
|
||||
res = ip->CurRendererRenderFrame( ip->GetTime(), bm, NULL, 1.0f, &vp );
|
||||
if( !res )
|
||||
goto fail;
|
||||
|
||||
if( !IWriteBM( &biOutFile, bm, thisFilename ) )
|
||||
goto fail;
|
||||
}
|
||||
|
||||
success = 1;
|
||||
fail:
|
||||
ip->CloseCurRenderer();
|
||||
ip->SetUseEnvironmentMap( saveUseEnvMap );
|
||||
|
||||
bm->DeleteThis();
|
||||
node->Hide( wasHid );
|
||||
if( success )
|
||||
{
|
||||
for(int i = 0; i < 6; i++ )
|
||||
{
|
||||
BitmapInfo bi;
|
||||
thisFilename.printf( _T( "%s\\%s%s%s" ), path, filename, suffixes[ i ], ext );
|
||||
bi.SetName( thisFilename );
|
||||
|
||||
PBBitmap pbBitmap( bi );
|
||||
fBitmapPB->SetValue( kBmpFrontBitmap + i, ip->GetTime(), &pbBitmap );
|
||||
}
|
||||
fBitmapPB->GetMap()->UpdateUI( ip->GetTime() );
|
||||
}
|
||||
}
|
||||
|
||||
PBBitmap *plStaticEnvLayer::GetPBBitmap(int index /* = 0 */)
|
||||
{
|
||||
return fBitmapPB->GetBitmap( ParamID( kBmpFrontBitmap + index ) );
|
||||
}
|
||||
|
||||
void plStaticEnvLayer::ISetPBBitmap( PBBitmap *pbbm, int index )
|
||||
{
|
||||
fBitmapPB->SetValue( ParamID( kBmpFrontBitmap + index ), 0, pbbm );
|
||||
}
|
@ -0,0 +1,237 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plStaticEnvLayer - Static EnvironmentMap MAX Layer //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 8.17.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plStaticEnvLayer_h
|
||||
#define _plStaticEnvLayer_h
|
||||
|
||||
#include "Max.h"
|
||||
#include "plPlasmaMAXLayer.h"
|
||||
#include "../resource.h"
|
||||
|
||||
class ClassDesc2;
|
||||
class IParamBlock2;
|
||||
class Bitmap;
|
||||
|
||||
ClassDesc2* GetStaticEnvLayerDesc();
|
||||
|
||||
extern TCHAR *GetString(int id);
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
|
||||
//// Class Definition /////////////////////////////////////////////////////////
|
||||
|
||||
class plStaticEnvLayer : public plPlasmaMAXLayer
|
||||
{
|
||||
protected:
|
||||
// Parameter block
|
||||
IParamBlock2 *fBitmapPB;
|
||||
UVGen *fUVGen;
|
||||
|
||||
IMtlParams *fIMtlParams;
|
||||
|
||||
TexHandle *fTexHandle;
|
||||
TimeValue fTexTime;
|
||||
|
||||
Bitmap *fBitmaps[ 6 ];
|
||||
Interval fIValid;
|
||||
TCHAR fBaseFileName[ MAX_PATH ];
|
||||
|
||||
friend class SELBitmapDlgProc;
|
||||
|
||||
|
||||
Matrix3 IGetViewTM( int i );
|
||||
int IWriteBM( BitmapInfo *bi, Bitmap *bm, TCHAR *name );
|
||||
|
||||
public:
|
||||
// Ref nums
|
||||
enum
|
||||
{
|
||||
kRefUVGen,
|
||||
kRefBitmap,
|
||||
};
|
||||
|
||||
// Block ID's
|
||||
enum
|
||||
{
|
||||
kBlkBitmap,
|
||||
};
|
||||
|
||||
// Faces
|
||||
enum
|
||||
{
|
||||
kFrontFace,
|
||||
kBackFace,
|
||||
kLeftFace,
|
||||
kRightFace,
|
||||
kTopFace,
|
||||
kBottomFace
|
||||
};
|
||||
|
||||
plStaticEnvLayer();
|
||||
~plStaticEnvLayer();
|
||||
void DeleteThis() { delete this; }
|
||||
|
||||
//From MtlBase
|
||||
ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
|
||||
BOOL SetDlgThing(ParamDlg* dlg);
|
||||
void Update(TimeValue t, Interval& valid);
|
||||
void Reset();
|
||||
Interval Validity(TimeValue t);
|
||||
ULONG LocalRequirements(int subMtlNum);
|
||||
|
||||
//From Texmap
|
||||
RGBA EvalColor(ShadeContext& sc);
|
||||
float EvalMono(ShadeContext& sc);
|
||||
Point3 EvalNormalPerturb(ShadeContext& sc);
|
||||
|
||||
// For displaying textures in the viewport
|
||||
BOOL SupportTexDisplay() { return TRUE; }
|
||||
void ActivateTexDisplay(BOOL onoff);
|
||||
BITMAPINFO *GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono=FALSE, int forceW=0, int forceH=0);
|
||||
DWORD GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
|
||||
protected:
|
||||
void IChanged();
|
||||
void IDiscardTexHandle();
|
||||
|
||||
public:
|
||||
void GetUVTransform(Matrix3 &uvtrans) { fUVGen->GetUVTransform(uvtrans); }
|
||||
int GetTextureTiling() { return fUVGen->GetTextureTiling(); }
|
||||
int GetUVWSource() { return fUVGen->GetUVWSource(); }
|
||||
virtual int GetMapChannel () { return fUVGen->GetMapChannel(); } // only relevant if above returns UVWSRC_EXPLICIT
|
||||
UVGen *GetTheUVGen() { return fUVGen; }
|
||||
|
||||
//TODO: Return anim index to reference index
|
||||
int SubNumToRefNum(int subNum) { return subNum; }
|
||||
|
||||
|
||||
// Loading/Saving
|
||||
IOResult Load(ILoad *iload);
|
||||
IOResult Save(ISave *isave);
|
||||
|
||||
//From Animatable
|
||||
Class_ID ClassID() { return STATIC_ENV_LAYER_CLASS_ID; }
|
||||
SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
|
||||
void GetClassName(TSTR& s) { s = GetString(IDS_STATIC_ENVMAP_LAYER); }
|
||||
|
||||
RefTargetHandle Clone( RemapDir &remap );
|
||||
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
||||
PartID& partID, RefMessage message);
|
||||
|
||||
int NumSubs();
|
||||
Animatable* SubAnim(int i);
|
||||
TSTR SubAnimName(int i);
|
||||
|
||||
// TODO: Maintain the number or references here
|
||||
int NumRefs();
|
||||
RefTargetHandle GetReference(int i);
|
||||
void SetReference(int i, RefTargetHandle rtarg);
|
||||
|
||||
int NumParamBlocks(); // return number of ParamBlocks in this instance
|
||||
IParamBlock2* GetParamBlock(int i); // return i'th ParamBlock
|
||||
IParamBlock2* GetParamBlockByID(BlockID id); // return id'd ParamBlock
|
||||
|
||||
const char *GetTextureName( int which );
|
||||
|
||||
void SetBaseFilename( const TCHAR *name, TimeValue t );
|
||||
const TCHAR *GetBaseFilename( TimeValue t );
|
||||
|
||||
void RenderCubicMap( INode *node );
|
||||
|
||||
|
||||
/// ParamBlock accessors
|
||||
enum
|
||||
{
|
||||
kScalingAny,
|
||||
kScalingHalf,
|
||||
kScalingNone
|
||||
};
|
||||
|
||||
// Param ID's
|
||||
enum
|
||||
{
|
||||
kBmpFrontBitmap,
|
||||
kBmpBackBitmap,
|
||||
kBmpLeftBitmap,
|
||||
kBmpRightBitmap,
|
||||
kBmpTopBitmap,
|
||||
kBmpBottomBitmap,
|
||||
|
||||
// Misc
|
||||
kBmpDiscardColor,
|
||||
kBmpInvertColor,
|
||||
kBmpDiscardAlpha,
|
||||
kBmpInvertAlpha,
|
||||
|
||||
// Texture quality
|
||||
kBmpNonCompressed,
|
||||
kBmpScaling,
|
||||
|
||||
// Max only
|
||||
kBmpMonoOutput,
|
||||
kBmpRGBOutput,
|
||||
|
||||
// Detail
|
||||
kBmpUseDetail,
|
||||
kBmpDetailStartSize,
|
||||
kBmpDetailStopSize,
|
||||
kBmpDetailStartOpac,
|
||||
kBmpDetailStopOpac,
|
||||
|
||||
// Texture generation
|
||||
kBmpBaseFilename,
|
||||
kBmpTextureSize,
|
||||
kBmpGenerateFaces,
|
||||
kBmpLastTextureSize, // Annoying, but necessary to clamp texture sizes to powers of 2
|
||||
kBmpUseMAXAtmosphere,
|
||||
kBmpFarDistance,
|
||||
|
||||
// Just a hack to simulate refraction instead of reflection
|
||||
kBmpRefract
|
||||
};
|
||||
|
||||
// Pure virtual accessors for the various bitmap related elements
|
||||
virtual Bitmap *GetMaxBitmap(int index = 0) { return fBitmaps[ index ]; }
|
||||
virtual PBBitmap *GetPBBitmap( int index = 0 );
|
||||
virtual int GetNumBitmaps( void ) { return 6; }
|
||||
|
||||
protected:
|
||||
virtual void ISetMaxBitmap(Bitmap *bitmap, int index = 0) { fBitmaps[ index ] = bitmap; }
|
||||
virtual void ISetPBBitmap( PBBitmap *pbbm, int index = 0 );
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // _plStaticEnvLayer_h
|
@ -0,0 +1,499 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plStaticEnvLayer.h"
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// Bitmap Accessor //////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class SELBMTexPBAccessor : public PBAccessor
|
||||
{
|
||||
public:
|
||||
void Set(PB2Value& val, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t)
|
||||
{
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
plStaticEnvLayer* layer = (plStaticEnvLayer*)owner;
|
||||
IParamBlock2 *pb = layer->GetParamBlockByID(plStaticEnvLayer::kBlkBitmap);
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case plStaticEnvLayer::kBmpFrontBitmap:
|
||||
case plStaticEnvLayer::kBmpBackBitmap:
|
||||
case plStaticEnvLayer::kBmpLeftBitmap:
|
||||
case plStaticEnvLayer::kBmpRightBitmap:
|
||||
case plStaticEnvLayer::kBmpTopBitmap:
|
||||
case plStaticEnvLayer::kBmpBottomBitmap:
|
||||
// Set up the enums so these would match...
|
||||
if (pb->GetMap())
|
||||
pb->GetMap()->Invalidate( id );
|
||||
// Update the bitmap saved by the layer
|
||||
//layer->SetBitmap( id, &val.bm->bi );
|
||||
break;
|
||||
|
||||
case plStaticEnvLayer::kBmpBaseFilename:
|
||||
if( pb->GetMap() )
|
||||
{
|
||||
pb->GetMap()->Enable( plStaticEnvLayer::kBmpGenerateFaces, ( val.s == NULL || val.s[ 0 ] == 0 ) ? FALSE : TRUE );
|
||||
|
||||
ICustButton *bmSelectBtn = GetICustButton( GetDlgItem( pb->GetMap()->GetHWnd(), IDC_GENERATE_FACES ) );
|
||||
bmSelectBtn->SetText( _T( "Generate From Node" ) );
|
||||
ReleaseICustButton( bmSelectBtn );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval &valid)
|
||||
{
|
||||
}
|
||||
};
|
||||
static SELBMTexPBAccessor bmtex_accessor;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// PickControlNode //////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class PickControlNode : public PickObjectProc
|
||||
{
|
||||
public:
|
||||
plStaticEnvLayer *fLayer;
|
||||
HWND fHWnd;
|
||||
|
||||
PickControlNode() { fLayer = NULL; }
|
||||
|
||||
BOOL Pick( INode *node )
|
||||
{
|
||||
if( node && fLayer )
|
||||
fLayer->RenderCubicMap( node );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void EnterMode()
|
||||
{
|
||||
ICustButton *iBut = GetICustButton( GetDlgItem( fHWnd, IDC_GENERATE_FACES ) );
|
||||
if( iBut )
|
||||
{
|
||||
iBut->SetCheck( TRUE );
|
||||
iBut->SetText( _T( "Generate From Node" ) );
|
||||
}
|
||||
ReleaseICustButton( iBut );
|
||||
}
|
||||
|
||||
void ExitMode()
|
||||
{
|
||||
ICustButton *iBut = GetICustButton( GetDlgItem( fHWnd, IDC_GENERATE_FACES ) );
|
||||
if( iBut )
|
||||
{
|
||||
iBut->SetCheck( FALSE );
|
||||
iBut->SetText( _T( "Generate From Node" ) );
|
||||
}
|
||||
ReleaseICustButton( iBut );
|
||||
}
|
||||
|
||||
BOOL Filter( INode *node ) { return TRUE; }
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// ParamBlock Dialog Proc ///////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SELBitmapDlgProc : public ParamMap2UserDlgProc
|
||||
{
|
||||
PickControlNode fPickCallback;
|
||||
|
||||
public:
|
||||
IMtlParams *fMtlParams;
|
||||
|
||||
/// Called to update the controls of the dialog
|
||||
virtual void Update( TimeValue t, Interval &valid, IParamMap2 *map )
|
||||
{
|
||||
ICustButton *bmSelectBtn;
|
||||
IParamBlock2 *pblock;
|
||||
int i;
|
||||
long buttons[ 6 ] = { IDC_FRONT_NAME, IDC_BACK_NAME, IDC_LEFT_NAME, IDC_RIGHT_NAME, IDC_TOP_NAME, IDC_BOTTOM_NAME };
|
||||
BitmapInfo bi;
|
||||
|
||||
|
||||
ParamMap2UserDlgProc::Update( t, valid, map );
|
||||
|
||||
pblock = map->GetParamBlock();
|
||||
for( i = plStaticEnvLayer::kBmpFrontBitmap; i <= plStaticEnvLayer::kBmpBottomBitmap; i++ )
|
||||
{
|
||||
bmSelectBtn = GetICustButton( GetDlgItem( map->GetHWnd(), buttons[ i ] ) );
|
||||
PBBitmap *pbbm = pblock->GetBitmap( i, t );
|
||||
if( pbbm )
|
||||
bmSelectBtn->SetText( (TCHAR *)pbbm->bi.Filename() );
|
||||
else
|
||||
bmSelectBtn->SetText( _T( "None" ) );
|
||||
ReleaseICustButton( bmSelectBtn );
|
||||
}
|
||||
|
||||
plStaticEnvLayer *layer = (plStaticEnvLayer *)map->GetParamBlock()->GetOwner();
|
||||
bi.SetName( layer->GetBaseFilename( t ) );
|
||||
SetDlgItemText( map->GetHWnd(), IDC_BASE_FILENAME, bi.Filename() );
|
||||
map->Enable( plStaticEnvLayer::kBmpGenerateFaces, ( bi.Name() == NULL || bi.Name()[ 0 ] == 0 ) ? FALSE : TRUE );
|
||||
|
||||
bmSelectBtn = GetICustButton( GetDlgItem( map->GetHWnd(), IDC_GENERATE_FACES ) );
|
||||
bmSelectBtn->SetText( _T( "Generate From Node" ) );
|
||||
ReleaseICustButton( bmSelectBtn );
|
||||
|
||||
i = pblock->GetInt( plStaticEnvLayer::kBmpTextureSize, t );
|
||||
pblock->SetValue( plStaticEnvLayer::kBmpLastTextureSize, t, i );
|
||||
}
|
||||
|
||||
/// Clamp texture sizes to a power of 2
|
||||
void IClampTexSizeSpinner( TimeValue t, IParamMap2 *map )
|
||||
{
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
|
||||
int lastVal = pblock->GetInt( plStaticEnvLayer::kBmpLastTextureSize, t );
|
||||
int tempVal, newVal = pblock->GetInt( plStaticEnvLayer::kBmpTextureSize, t );
|
||||
|
||||
if( newVal < lastVal )
|
||||
{
|
||||
lastVal = newVal;
|
||||
for( tempVal = 1; tempVal < newVal; tempVal <<= 1 );
|
||||
newVal = tempVal >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastVal = newVal;
|
||||
for( tempVal = 1; tempVal < newVal; tempVal <<= 1 );
|
||||
newVal = tempVal;
|
||||
}
|
||||
|
||||
pblock->SetValue( plStaticEnvLayer::kBmpTextureSize, t, newVal );
|
||||
pblock->SetValue( plStaticEnvLayer::kBmpLastTextureSize, t, newVal );
|
||||
}
|
||||
|
||||
/// Main message proc
|
||||
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static ICustButton* bmSelectBtn;
|
||||
long buttons[ 6 ] = { IDC_FRONT_NAME, IDC_BACK_NAME, IDC_LEFT_NAME, IDC_RIGHT_NAME, IDC_TOP_NAME, IDC_BOTTOM_NAME };
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
break;
|
||||
|
||||
case CC_SPINNER_CHANGE:
|
||||
if( LOWORD( wParam ) == IDC_TEXSIZE_SPIN )
|
||||
IClampTexSizeSpinner( t, map );
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
if( HIWORD( wParam ) == EN_CHANGE && LOWORD( wParam ) == IDC_TEXSIZE_EDIT )
|
||||
{
|
||||
IClampTexSizeSpinner( t, map );
|
||||
}
|
||||
else if( HIWORD( wParam ) == BN_CLICKED && LOWORD( wParam ) == IDC_LAYER_RELOAD )
|
||||
{
|
||||
plStaticEnvLayer *layer = (plStaticEnvLayer*)map->GetParamBlock()->GetOwner();
|
||||
layer->RefreshBitmaps();
|
||||
layer->IChanged();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if( LOWORD( wParam ) == IDC_FRONT_NAME )
|
||||
return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kFrontFace, map, t, hWnd );
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_BACK_NAME )
|
||||
return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kBackFace, map, t, hWnd );
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_LEFT_NAME )
|
||||
return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kLeftFace, map, t, hWnd );
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_RIGHT_NAME )
|
||||
return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kRightFace, map, t, hWnd );
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_TOP_NAME )
|
||||
return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kTopFace, map, t, hWnd );
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_BOTTOM_NAME )
|
||||
return IDoLayerClicked( LOWORD( wParam ), plStaticEnvLayer::kBottomFace, map, t, hWnd );
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_LAYER_LOAD_GEN )
|
||||
return IDoLoadGenerated( map, t, hWnd );
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_GENERATE_FACES )
|
||||
{
|
||||
plStaticEnvLayer *layer = (plStaticEnvLayer*)map->GetParamBlock()->GetOwner();
|
||||
|
||||
fMtlParams->EndPickMode();
|
||||
fPickCallback.fHWnd = hWnd;
|
||||
fPickCallback.fLayer = layer;
|
||||
|
||||
fMtlParams->SetPickMode( &fPickCallback );
|
||||
break;
|
||||
}
|
||||
|
||||
else if( LOWORD( wParam ) == IDC_BASE_FILENAME )
|
||||
return IDoSelectBaseFilename( map, t, hWnd );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
void DeleteThis() {};
|
||||
|
||||
BOOL IDoSelectBaseFilename( IParamMap2 *map, TimeValue t, HWND hWnd )
|
||||
{
|
||||
BitmapInfo bi;
|
||||
|
||||
|
||||
plStaticEnvLayer *layer = (plStaticEnvLayer*)map->GetParamBlock()->GetOwner();
|
||||
|
||||
/// Select one file
|
||||
bi.SetName( layer->GetBaseFilename( t ) );
|
||||
if( !TheManager->SelectFileOutput( &bi, GetCOREInterface()->GetMAXHWnd(), _T( "Choose the base filename for the rendered faces" ) ) )
|
||||
return FALSE;
|
||||
|
||||
/// Just store the name and set the button label as such, too
|
||||
SetDlgItemText( hWnd, IDC_BASE_FILENAME, bi.Filename() );
|
||||
layer->SetBaseFilename( bi.Name(), t );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL IDoLoadGenerated( IParamMap2 *map, TimeValue t, HWND hWnd )
|
||||
{
|
||||
BitmapInfo bi;
|
||||
int i;
|
||||
TCHAR filename[ MAX_PATH ];
|
||||
TCHAR *modPoint, faces[ 6 ][ 4 ] = { "_FR", "_BK", "_LF", "_RT", "_UP", "_DN" };
|
||||
|
||||
|
||||
/// Select one file
|
||||
PBBitmap *pbbm = map->GetParamBlock()->GetBitmap( plStaticEnvLayer::kBmpFrontBitmap, t );
|
||||
if( pbbm != NULL )
|
||||
bi.SetName( pbbm->bi.Name() );
|
||||
if( !TheManager->SelectFileInput( &bi, GetCOREInterface()->GetMAXHWnd(), _T( "Select one of the generated face bitmaps" ) ) )
|
||||
return FALSE;
|
||||
|
||||
/// Copy the name over and get our mod point
|
||||
strcpy( filename, bi.Filename() );
|
||||
modPoint = strstr( filename, "_UP" );
|
||||
if( modPoint == NULL )
|
||||
modPoint = strstr( filename, "_DN" );
|
||||
if( modPoint == NULL )
|
||||
modPoint = strstr( filename, "_LF" );
|
||||
if( modPoint == NULL )
|
||||
modPoint = strstr( filename, "_RT" );
|
||||
if( modPoint == NULL )
|
||||
modPoint = strstr( filename, "_FR" );
|
||||
if( modPoint == NULL )
|
||||
modPoint = strstr( filename, "_BK" );
|
||||
|
||||
/// Load each face
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
memcpy( modPoint, faces[ i ], sizeof( TCHAR ) * 3 );
|
||||
if( !ILoadFace( i, filename, map, t, hWnd ) )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ILoadFace( int whichFace, const TCHAR *fileName, IParamMap2 *map, TimeValue t, HWND hWnd )
|
||||
{
|
||||
long buttons[ 6 ] = { IDC_FRONT_NAME, IDC_BACK_NAME, IDC_LEFT_NAME, IDC_RIGHT_NAME, IDC_TOP_NAME, IDC_BOTTOM_NAME };
|
||||
|
||||
IParamBlock2 *pblock = map->GetParamBlock();
|
||||
plStaticEnvLayer *layer = (plStaticEnvLayer*)map->GetParamBlock()->GetOwner();
|
||||
ICustButton *bmSelectBtn;
|
||||
BitmapInfo bi;
|
||||
|
||||
|
||||
if( TheManager->GetImageInfo( &bi, fileName ) != BMMRES_SUCCESS )
|
||||
return FALSE;
|
||||
|
||||
layer->SetBitmap( &bi, whichFace - plStaticEnvLayer::kFrontFace );
|
||||
|
||||
PBBitmap *pbbm = layer->GetPBBitmap( whichFace - plStaticEnvLayer::kFrontFace );
|
||||
bmSelectBtn = GetICustButton( GetDlgItem( hWnd, buttons[ whichFace ] ) );
|
||||
bmSelectBtn->SetText((TCHAR*)pbbm->bi.Filename());
|
||||
ReleaseICustButton( bmSelectBtn );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL IDoLayerClicked( int whichBtn, int whichFace, IParamMap2 *map, TimeValue t, HWND hWnd )
|
||||
{
|
||||
plPlasmaMAXLayer *layer = (plPlasmaMAXLayer *)map->GetParamBlock()->GetOwner();
|
||||
if (layer == nil)
|
||||
return FALSE;
|
||||
|
||||
BOOL selectedNewBitmap = layer->HandleBitmapSelection( whichFace - plStaticEnvLayer::kFrontFace );
|
||||
if(selectedNewBitmap)
|
||||
{
|
||||
ICustButton* bmSelectBtn;
|
||||
|
||||
PBBitmap *pbbm = layer->GetPBBitmap( whichFace - plStaticEnvLayer::kFrontFace );
|
||||
bmSelectBtn = GetICustButton( GetDlgItem( hWnd, whichBtn ) );
|
||||
bmSelectBtn->SetText(pbbm != nil ? (TCHAR*)pbbm->bi.Filename() : nil);
|
||||
ReleaseICustButton(bmSelectBtn);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
};
|
||||
static SELBitmapDlgProc gSELBitmapDlgProc;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// ParamBlock Definition ////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static ParamBlockDesc2 gBitmapParamBlk
|
||||
(
|
||||
plStaticEnvLayer::kBlkBitmap, _T("bitmap"), 0, GetStaticEnvLayerDesc(),//NULL,
|
||||
P_AUTO_CONSTRUCT + P_AUTO_UI, plStaticEnvLayer::kRefBitmap,
|
||||
|
||||
IDD_STATIC_ENVMAP_LAYER, IDS_STATIC_ENVMAP_LAYER_TEX, 0, 0, &gSELBitmapDlgProc,
|
||||
|
||||
// Bitmaps
|
||||
plStaticEnvLayer::kBmpFrontBitmap, _T("frontBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpBackBitmap, _T("backBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpLeftBitmap, _T("leftBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpRightBitmap, _T("rightBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpTopBitmap, _T("topBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpBottomBitmap, _T("bottomBitmap"), TYPE_BITMAP, P_SHORT_LABELS, 0,
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
|
||||
// Texture Color/Alpha
|
||||
plStaticEnvLayer::kBmpDiscardColor, _T("discardColor"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_NO_COLOR,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpInvertColor, _T("invertColor"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_INV_COLOR,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpDiscardAlpha, _T("discardAlpha"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_DISCARD_ALPHA,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpInvertAlpha, _T("invertAlpha"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_BLEND_INV_ALPHA,
|
||||
end,
|
||||
|
||||
// Texture Quality
|
||||
plStaticEnvLayer::kBmpNonCompressed, _T("nonCompressed"),TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_FORCE_NONCOMPRESSED,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpScaling, _T("scaling"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_RADIO, 3, IDC_SCALE_ALL, IDC_SCALE_HALF, IDC_SCALE_NONE,
|
||||
end,
|
||||
|
||||
// Max Only
|
||||
plStaticEnvLayer::kBmpMonoOutput, _T("monoOutput"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_RADIO, 2, IDC_HSMAX_LAYER_RGBOUT, IDC_HSMAX_LAYER_ALPHAOUT,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpRGBOutput, _T("rgbOutput"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_RADIO, 2, IDC_HSMAX_LAYER_RGBOUT2, IDC_HSMAX_LAYER_ALPHAOUT2,
|
||||
end,
|
||||
|
||||
// Detail
|
||||
plStaticEnvLayer::kBmpUseDetail, _T("useDetail"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_USE_DETAIL,
|
||||
p_default, FALSE,
|
||||
p_enable_ctrls, 4, plStaticEnvLayer::kBmpDetailStartSize, plStaticEnvLayer::kBmpDetailStopSize,
|
||||
plStaticEnvLayer::kBmpDetailStartOpac, plStaticEnvLayer::kBmpDetailStopOpac,
|
||||
end,
|
||||
|
||||
plStaticEnvLayer::kBmpDetailStartSize,_T("dropOffStart"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_START_SIZE_EDIT, IDC_DETAIL_START_SIZE_SPIN, 0.4,
|
||||
p_range, 0, 100,
|
||||
p_default, 0,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpDetailStopSize, _T("dropOffStop"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_STOP_SIZE_EDIT, IDC_DETAIL_STOP_SIZE_SPIN, 0.4,
|
||||
p_range, 0, 100,
|
||||
p_default, 100,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpDetailStartOpac, _T("detailMax"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_START_OPAC_EDIT, IDC_DETAIL_START_OPAC_SPIN, 0.4,
|
||||
p_range, 0, 100,
|
||||
p_default, 8,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpDetailStopOpac, _T("detailMin"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_DETAIL_STOP_OPAC_EDIT, IDC_DETAIL_STOP_OPAC_SPIN, 0.4,
|
||||
p_range, 0, 100,
|
||||
p_default, 0,
|
||||
end,
|
||||
|
||||
// Face generation
|
||||
plStaticEnvLayer::kBmpTextureSize, _T("textureSize"), TYPE_INT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_TEXSIZE_EDIT, IDC_TEXSIZE_SPIN, SPIN_AUTOSCALE,
|
||||
p_range, 4, 512,
|
||||
p_default, 64,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpBaseFilename, _T("baseFilename"), TYPE_FILENAME, 0, 0,
|
||||
p_default, _T( "" ),
|
||||
p_accessor, &bmtex_accessor,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpGenerateFaces, _T("genFaces"), TYPE_INODE, 0, 0,
|
||||
p_ui, TYPE_PICKNODEBUTTON, IDC_GENERATE_FACES,
|
||||
p_prompt, IDS_SELECT_NODE,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpUseMAXAtmosphere, _T("useMAXAtmos"), TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_USEMAXFOG,
|
||||
p_default, FALSE,
|
||||
p_enable_ctrls, 1, plStaticEnvLayer::kBmpFarDistance,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpFarDistance, _T("farDistance"), TYPE_FLOAT, 0, 0,
|
||||
p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_FARDIST_EDIT, IDC_FARDIST_SPIN, SPIN_AUTOSCALE,
|
||||
p_range, 0.f, 9999999.f,
|
||||
p_default, 500.f,
|
||||
end,
|
||||
plStaticEnvLayer::kBmpLastTextureSize, _T("lastTextureSize"), TYPE_INT, 0, 0,
|
||||
end,
|
||||
|
||||
plStaticEnvLayer::kBmpRefract, _T("refract"),TYPE_BOOL, 0, 0,
|
||||
p_ui, TYPE_SINGLECHEKBOX, IDC_REFRACT,
|
||||
end,
|
||||
|
||||
end
|
||||
);
|
||||
|
@ -0,0 +1,72 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// ParamBlock Konstants for Static EnvironmentMap MAX Layers //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 8.17.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plStaticEnvLayerBitmapPB_h
|
||||
#define _plStaticEnvLayerBitmapPB_h
|
||||
|
||||
// Param ID's
|
||||
enum
|
||||
{
|
||||
kBmpFrontBitmap,
|
||||
kBmpBackBitmap,
|
||||
kBmpLeftBitmap,
|
||||
kBmpRightBitmap,
|
||||
kBmpTopBitmap,
|
||||
kBmpBottomBitmap,
|
||||
|
||||
// Misc
|
||||
kBmpDiscardColor,
|
||||
kBmpInvertColor,
|
||||
kBmpDiscardAlpha,
|
||||
kBmpInvertAlpha,
|
||||
|
||||
// Texture quality
|
||||
kBmpNonCompressed,
|
||||
kBmpScaling,
|
||||
|
||||
// Max only
|
||||
kBmpMonoOutput,
|
||||
kBmpRGBOutput,
|
||||
|
||||
// Detail
|
||||
kBmpUseDetail,
|
||||
kBmpDetailStartSize,
|
||||
kBmpDetailStopSize,
|
||||
kBmpDetailStartOpac,
|
||||
kBmpDetailStopOpac,
|
||||
};
|
||||
|
||||
#endif //_plStaticEnvLayerBitmapPB_h
|
Reference in New Issue
Block a user