You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

511 lines
20 KiB

/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef PL_RTLIGHT_BASE_H
#define PL_RTLIGHT_BASE_H
// Our generic headers
#include "HeadSpin.h"
#include "hsWindows.h"
// Max related headers
#include <max.h>
#include <iparamm2.h>
#include "MaxMain/MaxCompat.h"
extern TCHAR *GetString(int id);
extern HINSTANCE hInstance;
#define RTOMNI_LIGHT_CLASSID Class_ID(0x57cf7089, 0x282e5b71)
#define RTSPOT_LIGHT_CLASSID Class_ID(0x2b263fdd, 0x19c4351f)
#define RTTSPOT_LIGHT_CLASSID Class_ID(0x48cb06ab, 0x3c142832)
#define RTDIR_LIGHT_CLASSID Class_ID(0x5a6d278c, 0x780a78b1)
// Projected Directional Light
#define RTPDIR_LIGHT_CLASSID Class_ID(0x2f611934, 0x3681ff0)
#define FOREVER Interval(TIME_NegInfinity, TIME_PosInfinity)
#define DEF_TDIST 240.0f // 160.0f
#define NUM_HALF_ARC 5
#define NUM_ARC_PTS (2*NUM_HALF_ARC+1)
#define NUM_CIRC_PTS 28
#define SEG_INDEX 7
#define ATTEN_START 2 // far
#define ATTEN_END 3 // far
#define WM_SET_TYPE WM_USER + 0x04002
inline float MaxF(float a, float b) { return a>b?a:b; }
inline float MinF(float a, float b) { return a<b?a:b; }
class plLayerTex;
class plMaxNode;
class plRTLightBase;
///////////////////////////////////////////////////////////////////////////////
//// Base LightDlgProc ////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
class plBaseLightProc : public ParamMap2UserDlgProc
{
protected:
void ILoadComboBox( HWND hComboBox, const char *names[] );
void IBuildLightMesh( plRTLightBase *base, float coneSize );
public:
virtual BOOL DlgProc( TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
};
///////////////////////////////////////////////////////////////////////////////
//// plLightTexPBAccessor /////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
class plLightTexPBAccessor : public PBAccessor
{
public:
void Set( PB2Value& val, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t );
void Get( PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval &valid );
static plLightTexPBAccessor *Instance( void ) { return &fAccessor; }
protected:
static plLightTexPBAccessor fAccessor;
};
///////////////////////////////////////////////////////////////////////////////
//// plRTLightBase Class //////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
class plRTLightBase : public GenLight
{
protected:
ClassDesc2 *fClassDesc; // Must set in derived classes constructor
Color fColor; // Color of mesh
Mesh fMesh; // Mesh to draw
IParamBlock2 *fLightPB; // The derived component's paramblock (optional)
plLayerTex* fTex;
13 years ago
virtual bool IHasAttenuation( void ) { return false; }
virtual void IBuildMeshes( BOOL isNew ) {}
void BuildStaticMeshes();
void BuildSpotMesh(float coneSize);
int meshBuilt;
int extDispFlags;
Mesh staticMesh[2];
Mesh spotMesh;
public:
friend class plBaseLightProc;
friend class plLightTexPBAccessor;
friend class SetTypeRest;
ExclList exclList;
IObjParam *fIP;
enum LightType
{
RT_OMNI,
RT_TARGET_SPOT,
RT_FREE_SPOT,
RT_TARGET_DIR,
RT_FREE_DIR
};
//// NOTE /////////////////////////////////////////////////////////////////////
// I would've overhauled this entire system to be far more sane, but doing
// so would break every scene with RT lights that the artists have (as in
// they would crash and burn, or at best just not read in). As a result,
// as much as it annoys me to death, we can't do a damn thing about it.
// Hopefully, in the future we will be able to clean all of this out somehow
// (a conversion utility might come in handy, dunno).
//
// For reference, the setup SHOULD have separate paramBlocks for each rollout,
// using the P_USE_PARAMS to duplicate the shared ones, and all the rollouts
// should have *IDENTICAL* block and ref #s, so the shared code actually looks
// sane. The final block/ref #s needed would be kBlkMain, kBlkAnim, kBlkProj
// (for spots and proj dir) and kBlkAttenuation (projMaps don't need ref #s,
// since they're part of the paramBlocks).
///////////////////////////////////////////////////////////////////////////////
// Blk Numbers
enum BlkNumber
{
// Old numbers. Phase out when possible
kBlkGeneralLightProp,
kBlkAttenLightProp,
kBlkOmniLightProp,
kBlkOtherLightProp,
kBlkOmniLight,
kBlkSpotLight,
kBlkTSpotLight,
kBlkDirLight,
kBlkTDirLight,
// New ones
kBlkMain = 0,
kBlkAnim = 9,
kBlkDerivedStart = 20
};
// Ref numbers
enum RefNumber
{
kRefGeneralLightProp,
kRefProjMap,
kRefShadowProjMap,
kRefShadowType,
kRefOmniLight,
kRefSpotLight,
kRefTSpotLight,
kRefDirLight,
kRefTDirLight,
kRefProjDirLight,
kRefAnimParams_DEAD,
kNumRefs,
kRefDerivedStart = 30
};
//Multimap Support?
enum MapChoice
{
kLightMap1,
kLightMap2,
kLightMap3,
kLightMap4,
kLightMap5,
kLightMap6
};
enum ParamVals
{
kLightType, //Inserted in v1, Removed in v4
kAffectDiffuse, //Inserted in v1
kLightColor, //Inserted in v1
kLightExclude, //Inserted in v1
kCastShadows, //Inserted in v2, OBSOLETE
kIntensity, //Inserted in v1
kContrast, //Inserted in v1
kDiffSoft, //Inserted in v1
kDiffOn, //Inserted in v1
kSpec, //Inserted in v1
kAmbiOnly, //Inserted in v1
kStartAttenNear, //Inserted in v1, Removed in v3
kEndAttenNear, //Inserted in v1, Removed in v3
kUseNearAtten, //Inserted in v1, Removed in v3
kShowNearAttenRanges,//Inserted in v1, Removed in v3
kStartAttenFar, //Inserted in v1, Removed in v3
kEndAttenFar, //Inserted in v1, Removed in v3
kUseFarAtten, //Inserted in v1, Removed in v3
kShowFarAttenRanges, //Inserted in v1, Removed in v3
kLightDecay, //Inserted in v1, Removed in v3
kDecayEdit, //Inserted in v1, Removed in v3
kShowDecay, //Inserted in v1, Removed in v3
kUseProjectBool, //Inserted in v1
kProjMapTexButton, //Inserted in v1
kShowConeBool, //Inserted in v1
kOvershootBool, //Inserted in v1, Removed in v2
kHotSpot, //Inserted in v1
kFallOff, //Inserted in v1
kLightShapeRadio, //Inserted in v1, Removed in v2
kAspect, //Inserted in v1, Removed in v2
kUseProjectorBool, //Inserted in v1
kProjMapTexButton2, //Inserted in v1
kTargetDist, //Inserted in v1
kShadowOn, //Inserted in v2
kShadowChoice, //Inserted in v2
kUseShadGlobal, //Inserted in v2
kShadowColor, //Inserted in v2
kShadowDensity, //Inserted in v2
kUseShadMapBool, //Inserted in v2
kShadMapButton, //Inserted in v2
kLightColorEffects, //Inserted in v2
kAtmosShadowsBool, //Inserted in v2
kAtmosShadOpacity, //Inserted in v2
kAtmosShadColor, //Inserted in v2
kShadMapBias, //Inserted in v2
kShadMapSize, //Inserted in v2
kShadSampleRange, //Inserted in v2
kAbsoluteShadBias, //Inserted in v2
kUseAttenuationBool,//Inserted in v3
kAttenMaxFalloffEdit, //Inserted in v3
kAttenTypeRadio, //Inserted in v3
kSpecularColorSwatch,//Inserted in v3
kAttenSlider,
kLightOn,
kAmbientOnlyStub,
kProjTypeRadio,
kProjNoCompress,
kProjNoMip
};
// Projection types.
enum
{
kIlluminate,
kAdd,
kMult,
kMADD
};
// Animation rollout parameters
enum
{
kAnimName,
kAnimAutoStart,
kAnimLoop,
kAnimLoopName
};
plRTLightBase() { }//meshBuilt = 0; fClassDesc = NULL; fLightPB = NULL; fIP = NULL; BuildMeshes(true); }
virtual ~plRTLightBase();
void DeleteThis() { delete this; }
static ParamBlockDesc2 *GetAnimPBDesc( void );
TCHAR* GetObjectName() { return (TCHAR*)fClassDesc->ClassName(); }
void GetClassName(TSTR& s) { s = fClassDesc->ClassName(); }
virtual IParamBlock2 *GetParamBlock( int i );
virtual IParamBlock2* GetParamBlock2();
virtual IParamBlock2* GetParamBlockByID(short id);
plLayerTex* GetTex() { return fTex; }
// So our animatables will show up in the trackview
virtual int NumParamBlocks() { return 1; }
virtual int NumSubs();
virtual Animatable* SubAnim(int i);
virtual TSTR SubAnimName(int i);
// plug-in mouse creation callback
CreateMouseCallBack* GetCreateMouseCallBack();
RefTargetHandle Clone(RemapDir &remap = DEFAULTREMAP){ plRTLightBase* thisObj = new plRTLightBase(); BaseClone(this, thisObj, remap); return thisObj;}
virtual void BeginEditParams(IObjParam *ip, ULONG flags, Animatable *prev);
virtual void EndEditParams(IObjParam *ip, ULONG flags, Animatable *next);
// main function that will build our mesh
void FreeCaches();
// retreives bounding box in object space/world space
void GetLocalBoundBox(TimeValue t, INode *node, ViewExp *vpt, Box3 &box);
void GetWorldBoundBox(TimeValue t, INode *node, ViewExp *vpt, Box3 &box);
// main display function for this object
int Display(TimeValue t, INode *node, ViewExp *vpt, int flags);
virtual int DrawConeAndLine(TimeValue t, INode* inode, GraphicsWindow *gw, int drawing );
void GetConePoints(TimeValue t, float aspect, float angle, float dist, Point3 *q);
virtual void DrawCone(TimeValue t, GraphicsWindow *gw, float dist);
int GetSpotShape(void){ return 0; }
void SetExtendedDisplay(int flags){ extDispFlags = flags; }
void BoxCircle(TimeValue t, float r, float d, Box3& box, int extraPt, Matrix3 *tm);
void BoxDirPoints(TimeValue t, float angle, float dist, Box3 &box, Matrix3 *tm);
void BoxPoints(TimeValue t, float angle, float dist, Box3 &box, Matrix3 *tm);
void DrawArrow( TimeValue t, GraphicsWindow *gw, Point3 &direction, float dist );
void GetAttenPoints(TimeValue t, float rad, Point3 *q);
int GetRectXPoints(TimeValue t, float angle, float dist, Point3 *q);
int GetCirXPoints(TimeValue t, float angle, float dist, Point3 *q);
void DrawSphereArcs(TimeValue t, GraphicsWindow *gw, float r, Point3 *q);
//
void DrawX(TimeValue t, float asp, int npts, float dist, GraphicsWindow *gw, int indx);
void DrawCircleX(TimeValue t, GraphicsWindow *gw, float angle, float dist, Point3 *q);
void DrawWarpRect(TimeValue t, GraphicsWindow *gw, float angle, float dist, Point3 *q);
void DrawAttenCirOrRect(TimeValue t, GraphicsWindow *gw, float dist, BOOL froze, int uicol);
int DrawAtten(TimeValue t, INode *inode, GraphicsWindow *gw);
//void SetType(int tp);
// hit testing of this object
int HitTest(TimeValue t, INode *node, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt);
void Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt);
void GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm, BOOL useSel );
//Internal routines
void BoxLight(TimeValue t, INode *inode, Box3& box, Matrix3 *tm);
void GetMat(TimeValue t, INode* inode, ViewExp *vpt, Matrix3& tm);
virtual RefTargetHandle GetReference(int i);
virtual void SetReference(int ref, RefTargetHandle rtarg);
virtual int NumRefs() { return kNumRefs;}
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
// Called to retreive the state of this object at the specified time.
ObjectState Eval(TimeValue t) { return ObjectState(this); }
const char *GetCategory(){ return fClassDesc->Category(); }
//
// LightObject Specific Stuff below
//
//
virtual BOOL IsSpot( void ) { return FALSE; }
virtual BOOL IsDir( void ) { return FALSE; }
RefResult EvalLightState(TimeValue time, Interval& valid, LightState *ls);
ObjLightDesc *CreateLightDesc(INode *n, BOOL forceShadowBuffer=FALSE);
void SetUseLight(int onOff) { fLightPB->SetValue(kLightOn, 0, onOff); NotifyDependents(FOREVER, PART_OBJ, REFMSG_CHANGE); }
BOOL GetUseLight(void) { BOOL v; fLightPB->GetValue(kLightOn, 0, v, FOREVER); return v; }
void SetHotspot(TimeValue time, float f);
float GetHotspot(TimeValue t, Interval& valid = Interval(0,0));
void SetFallsize(TimeValue time, float f);
float GetFallsize(TimeValue t, Interval& valid = Interval(0,0));
void SetAtten(TimeValue time, int which, float f);
float GetAtten(TimeValue t, int which, Interval& valid = Interval(0,0));
// TDist funcs needs implementation as of 31/5/01
void SetTDist(TimeValue time, float f);
float GetTDist(TimeValue t, Interval& valid = Interval(0,0));
void SetConeDisplay(int s, int notify=TRUE);
BOOL GetConeDisplay(void);
void SetRGBColor(TimeValue t, Point3& rgb); //fLightPB->SetValue(kRGB, t, rgb); NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);}
Point3 GetRGBColor(TimeValue t, Interval &valid = Interval(0,0)); //return fLightPB->GetPoint3(kRGB, t); }
void SetIntensity(TimeValue t, float f) { fLightPB->SetValue(kIntensity, t, f); NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);}
float GetIntensity(TimeValue t, Interval& valid = Interval(0,0)) {return fLightPB->GetFloat(kIntensity, t); }
void SetAspect(TimeValue t, float f) {}
float GetAspect(TimeValue t, Interval& valid = Interval(0,0)) { return 0.0; }
void SetUseAtten(int s){ fLightPB->SetValue(kUseAttenuationBool, 0, s); NotifyDependents(FOREVER, PART_OBJ, REFMSG_CHANGE); }
BOOL GetUseAtten(void) {return fLightPB->GetInt(kUseAttenuationBool, 0);}
void SetUseAttenNear(int s) { }
BOOL GetUseAttenNear(void) {return false;}
void SetAttenDisplay(int s){ }
BOOL GetAttenDisplay(void) {return fLightPB->GetInt(kUseAttenuationBool, 0);}
void SetAttenDisplayNear(int s){ }
BOOL GetAttenDisplayNear(void){return false;}
void Enable(int enab) { fLightPB->SetValue(kLightOn, 0, enab); }
void SetMapBias(TimeValue t, float f) {}
float GetMapBias(TimeValue t, Interval& valid = Interval(0,0)){return 0.0f;}
void SetMapRange(TimeValue t, float f) {}
float GetMapRange(TimeValue t, Interval& valid = Interval(0,0)) {return 0.0f;}
void SetMapSize(TimeValue t, int f) {}
int GetMapSize(TimeValue t, Interval& valid = Interval(0,0)){return 0;}
void SetRayBias(TimeValue t, float f) {}
float GetRayBias(TimeValue t, Interval& valid = Interval(0,0)) {return 0.0;} //{return 0.0f;}
int GetAbsMapBias() {return 0;}
void SetAbsMapBias(int a) {}
int GetOvershoot(){return 0;}
void SetOvershoot(int a){}
virtual int GetProjector() { return 0; }
void SetProjector(int a){fLightPB->SetValue(kUseProjectorBool, 0, a); }
ExclList* GetExclList(){return NULL;}
BOOL Include() {return false;}
virtual Texmap* GetProjMap(); //{ Interval valid = Interval(0,0); Texmap* MyMap; fLightPB->GetValue(kProjMapTexButton, 0, MyMap, valid); return MyMap; }
void SetProjMap(BitmapInfo* pmap);
void UpdateTargDistance(TimeValue t, INode* inode);
// GenLight Specific Stuff below
BOOL GetUseGlobal() { return false; } //Global Shadow param
void SetUseGlobal(int a) {}
BOOL GetShadow();
void SetShadow(int a);
BOOL GetShadowType() { return -1; } //No Shadows generated ....
void SetShadowType(int a) {} //Until implemented....
GenLight* NewLight(int type) { return NULL;}
int Type() {return -1;}
void SetSpotShape(int a) {}
void SetHSVColor(TimeValue t, class Point3 &b);
Point3 GetHSVColor(TimeValue t, Interval& b);
void SetContrast(int a, float other) {} // fLightPB->SetValue(kContrast, a, other); NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);}
float GetContrast(int a, Interval &valid) {return 0.0;} //float f; f = fLightPB->GetFloat(kContrast, a); return f;}
void SetAttenNearDisplay(int a) {}
BOOL GetAttenNearDisplay() {return false;}
ExclList& GetExclusionList() {return exclList;}
void SetExclusionList(ExclList & a) {}
BOOL SetHotSpotControl(Control* a) {SetParamBlock2Controller(fLightPB, ParamID(kHotSpot),0, a); return true;}
BOOL SetFalloffControl(Control* a) {SetParamBlock2Controller(fLightPB, ParamID(kFallOff),0, a); return true;}
Control* GetHotSpotControl() {return GetParamBlock2Controller(fLightPB, ParamID(kHotSpot));}
Control* GetFalloffControl() {return GetParamBlock2Controller(fLightPB, ParamID(kFallOff));}
BOOL SetColorControl(Control * a) {SetParamBlock2Controller(fLightPB, ParamID(kLightColor),0, a); return true;}
Control* GetColorControl() {return GetParamBlock2Controller(fLightPB, ParamID(kLightColor)); }
BOOL GetDecayType() { return fLightPB->GetInt(kAttenTypeRadio, 0) + 1;} //Offset for the radio.
void SetDecayType(BOOL onOff) {if (!onOff) return; else {fLightPB->SetValue(kAttenTypeRadio, 0, ((int) onOff - 1)); return;} }
void SetDecayRadius(TimeValue time, float f) { fLightPB->SetValue(kAttenMaxFalloffEdit, time, f); }
float GetDecayRadius(TimeValue t, Interval& valid = Interval(0,0)) {return fLightPB->GetFloat(kAttenMaxFalloffEdit, t); }
void SetDiffuseSoft(TimeValue time, float f) {}//fLightPB->SetValue(kDiffSoft, time, f);}
float GetDiffuseSoft(TimeValue t, Interval& valid = Interval(0,0)) {return 0.0;} //return fLightPB->GetFloat(kDiffSoft, t);}
void SetAffectDiffuse(BOOL onOff) {}//fLightPB->SetValue(kDiffOn, 0, onOff); }
BOOL GetAffectDiffuse() {return false; } //fLightPB->GetInt(kDiffOn, 0); }
LRESULT CALLBACK TrackViewWinProc( HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam ){return(0);}
};
#endif