Files
firestorm/Gameleap/code/mw4/Tools/Max43DSPlugins/MaxControls/Noizctrl.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1599 lines
43 KiB
C++

/**********************************************************************
*<
FILE: noizctrl.cpp
DESCRIPTION: A simple noise controller
CREATED BY: Rolf Berteig
HISTORY: created 26 August 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "ctrl.h"
#include "units.h"
#include "noise.h"
#include "istdplug.h"
#define FLOATNOISE_CONTROL_CNAME GetString(IDS_RB_NOISEFLOAT)
#define POSITIONNOISE_CONTROL_CNAME GetString(IDS_RB_NOISEPOSITION)
#define POINT3NOISE_CONTROL_CNAME GetString(IDS_RB_NOISEPOINT3)
#define ROTATIONNOISE_CONTROL_CNAME GetString(IDS_RB_NOISEROTATION)
#define SCALENOISE_CONTROL_CNAME GetString(IDS_RB_NOISESCALE)
#define MAX_ELEMS 3
class BaseNoiseControl : public INoiseControl {
public:
//float strength[MAX_ELEMS];
Control *cont; // make strength animatable.
float frequency;
float roughness;
int seed;
BOOL fractal;
BOOL lim[MAX_ELEMS];
Interval range;
TimeValue rampin, rampout;
BaseNoiseControl();
BaseNoiseControl& operator=(const BaseNoiseControl& from);
float NoiseAtTime(TimeValue t,int s,int index);
virtual int Elems()=0;
// Animatable methods
void DeleteThis() {delete this;}
int IsKeyable() {return 0;}
BOOL IsAnimated() {return TRUE;}
int NumSubs();
Animatable* SubAnim(int i);
TSTR SubAnimName(int i);
BOOL AssignController(Animatable *control,int subAnim);
int SubNumToRefNum(int subNum);
int NumRefs();
RefTargetHandle GetReference(int i);
void SetReference(int i, RefTargetHandle rtarg);
void EditTrackParams(
TimeValue t,
ParamDimensionBase *dim,
TCHAR *pname,
HWND hParent,
IObjParam *ip,
DWORD flags);
int TrackParamsType() {return TRACKPARAMS_WHOLE;}
// Reference methods
RefResult NotifyRefChanged(Interval, RefTargetHandle, PartID&, RefMessage) {return REF_SUCCEED;}
IOResult Save(ISave *isave);
IOResult Load(ILoad *iload);
// Control methods
void Copy(Control *from) {}
BOOL IsLeaf() {return TRUE;}
void CommitValue(TimeValue t) {}
void RestoreValue(TimeValue t) {}
// From INoiseControl
void SetSeed(int seed);
void SetFrequency(float f);
void SetFractal(BOOL f);
void SetRoughness(float f);
void SetRampIn(TimeValue in);
void SetRampOut(TimeValue out);
void SetPositiveOnly(int which,BOOL onOff);
void SetStrengthController(Control *c);
float GetRoughness() {return roughness;}
int GetSeed() {return seed;}
float GetFrequency() {return frequency;}
BOOL GetFractal() {return fractal;}
TimeValue GetRampIn() {return rampin;}
TimeValue GetRampOut() {return rampout;}
BOOL GetPositiveOnly(int which) {return lim[which];}
Control *GetStrengthController() {return cont;}
void HoldRange();
Interval GetTimeRange(DWORD flags) {return range;}
void EditTimeRange(Interval range,DWORD flags);
void MapKeys(TimeMap *map,DWORD flags );
void GetStrength(TimeValue t,float *strength) {
cont->GetValue(t,strength,FOREVER);
}
};
//---------------------------------------------------------------------------
class FloatNoiseControl : public BaseNoiseControl {
public:
int Elems() {return 1;}
FloatNoiseControl() {
cont=NULL;
ReplaceReference(Control::NumRefs(),NewDefaultFloatController());
float v = 50.0f;
cont->SetValue(0,&v);
}
Class_ID ClassID() { return Class_ID(FLOATNOISE_CONTROL_CLASS_ID,0); }
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
void GetClassName(TSTR& s) {s = FLOATNOISE_CONTROL_CNAME;}
// Control methods
RefTargetHandle Clone(RemapDir& remap);
// StdControl methods
void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE);
void SetValueLocalTime(TimeValue t, void *val, int commit, GetSetMethod method) {}
void Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int type);
void *CreateTempValue() {return new float;}
void DeleteTempValue(void *val) {delete (float*)val;}
void ApplyValue(void *val, void *delta) {*((float*)val) += *((float*)delta);}
void MultiplyValue(void *val, float m) {*((float*)val) *= m;}
};
class FloatNoiseClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading) { return new FloatNoiseControl(); }
const TCHAR * ClassName() { return FLOATNOISE_CONTROL_CNAME; }
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
Class_ID ClassID() { return Class_ID(FLOATNOISE_CONTROL_CLASS_ID,0); }
const TCHAR* Category() { return _T(""); }
};
static FloatNoiseClassDesc floatNoiseCD;
ClassDesc* GetFloatNoiseDesc() {return &floatNoiseCD;}
//-----------------------------------------------------------------------------
class PositionNoiseControl : public BaseNoiseControl {
public:
int Elems() {return 3;}
PositionNoiseControl() {
cont=NULL;
ReplaceReference(Control::NumRefs(),NewDefaultPoint3Controller());
Point3 v(50.0f,50.0f,50.0f);
cont->SetValue(0,&v);
}
Class_ID ClassID() { return Class_ID(POSITIONNOISE_CONTROL_CLASS_ID,0); }
SClass_ID SuperClassID() { return CTRL_POSITION_CLASS_ID; }
void GetClassName(TSTR& s) {s = POSITIONNOISE_CONTROL_CNAME;}
// Control methods
RefTargetHandle Clone(RemapDir& remap);
// StdControl methods
void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE);
void SetValueLocalTime(TimeValue t, void *val, int commit, GetSetMethod method) {}
void Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int type);
void *CreateTempValue() {return new Point3;}
void DeleteTempValue(void *val) {delete (Point3*)val;}
void ApplyValue(void *val, void *delta) {((Matrix3*)val)->PreTranslate(*((Point3*)delta));}
void MultiplyValue(void *val, float m) {*((Point3*)val) *= m;}
};
class PositionNoiseClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading) { return new PositionNoiseControl(); }
const TCHAR * ClassName() { return POSITIONNOISE_CONTROL_CNAME; }
SClass_ID SuperClassID() { return CTRL_POSITION_CLASS_ID; }
Class_ID ClassID() { return Class_ID(POSITIONNOISE_CONTROL_CLASS_ID,0); }
const TCHAR* Category() { return _T(""); }
};
static PositionNoiseClassDesc positionNoiseCD;
ClassDesc* GetPositionNoiseDesc() {return &positionNoiseCD;}
//-----------------------------------------------------------------------------
class Point3NoiseControl : public BaseNoiseControl {
public:
int Elems() {return 3;}
Point3NoiseControl() {
cont=NULL;
ReplaceReference(Control::NumRefs(),NewDefaultPoint3Controller());
Point3 v(50.0f,50.0f,50.0f);
cont->SetValue(0,&v);
}
Class_ID ClassID() { return Class_ID(POINT3NOISE_CONTROL_CLASS_ID,0); }
SClass_ID SuperClassID() { return CTRL_POINT3_CLASS_ID; }
void GetClassName(TSTR& s) {s = POINT3NOISE_CONTROL_CNAME;}
// Control methods
RefTargetHandle Clone(RemapDir& remap);
// StdControl methods
void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE);
void SetValueLocalTime(TimeValue t, void *val, int commit, GetSetMethod method) {}
void Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int type);
void *CreateTempValue() {return new Point3;}
void DeleteTempValue(void *val) {delete (Point3*)val;}
void ApplyValue(void *val, void *delta) {*((Point3*)val) += *((Point3*)delta);}
void MultiplyValue(void *val, float m) {*((Point3*)val) *= m;}
};
class Point3NoiseClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading) { return new Point3NoiseControl(); }
const TCHAR * ClassName() { return POINT3NOISE_CONTROL_CNAME; }
SClass_ID SuperClassID() { return CTRL_POINT3_CLASS_ID; }
Class_ID ClassID() { return Class_ID(POINT3NOISE_CONTROL_CLASS_ID,0); }
const TCHAR* Category() { return _T(""); }
};
static Point3NoiseClassDesc point3NoiseCD;
ClassDesc* GetPoint3NoiseDesc() {return &point3NoiseCD;}
//-----------------------------------------------------------------------------
class RotationNoiseControl : public BaseNoiseControl {
public:
int Elems() {return 3;}
RotationNoiseControl() {
Point3 strength;
strength[0] = strength[1] = strength[2] = DegToRad(45);
cont=NULL;
ReplaceReference(Control::NumRefs(),NewDefaultPoint3Controller());
cont->SetValue(0,&strength);
}
Class_ID ClassID() { return Class_ID(ROTATIONNOISE_CONTROL_CLASS_ID,0); }
SClass_ID SuperClassID() { return CTRL_ROTATION_CLASS_ID; }
void GetClassName(TSTR& s) {s = ROTATIONNOISE_CONTROL_CNAME;}
// Control methods
RefTargetHandle Clone(RemapDir& remap);
// StdControl methods
void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE);
void SetValueLocalTime(TimeValue t, void *val, int commit, GetSetMethod method) {}
void Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int type);
void *CreateTempValue() {return new Quat;}
void DeleteTempValue(void *val) {delete (Quat*)val;}
void ApplyValue(void *val, void *delta) {PreRotateMatrix( *((Matrix3*)val), *((Quat*)delta) );}
void MultiplyValue(void *val, float m) {*((Quat*)val) *= m;}
};
class RotationNoiseClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading) { return new RotationNoiseControl(); }
const TCHAR * ClassName() { return ROTATIONNOISE_CONTROL_CNAME; }
SClass_ID SuperClassID() { return CTRL_ROTATION_CLASS_ID; }
Class_ID ClassID() { return Class_ID(ROTATIONNOISE_CONTROL_CLASS_ID,0); }
const TCHAR* Category() { return _T(""); }
};
static RotationNoiseClassDesc rotationNoiseCD;
ClassDesc* GetRotationNoiseDesc() {return &rotationNoiseCD;}
//-----------------------------------------------------------------------------
class ScaleNoiseControl : public BaseNoiseControl {
public:
int Elems() {return 3;}
ScaleNoiseControl() {
Point3 strength;
strength[0] = strength[1] = strength[2] = 0.5f;
cont=NULL;
ReplaceReference(Control::NumRefs(),NewDefaultPoint3Controller());
cont->SetValue(0,&strength);
}
Class_ID ClassID() { return Class_ID(SCALENOISE_CONTROL_CLASS_ID,0); }
SClass_ID SuperClassID() { return CTRL_SCALE_CLASS_ID; }
void GetClassName(TSTR& s) {s = SCALENOISE_CONTROL_CNAME;}
// Control methods
RefTargetHandle Clone(RemapDir& remap);
// StdControl methods
void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE);
void SetValueLocalTime(TimeValue t, void *val, int commit, GetSetMethod method) {}
void Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int type);
void *CreateTempValue() {return new ScaleValue;}
void DeleteTempValue(void *val) {delete (ScaleValue*)val;}
void ApplyValue(void *val, void *delta) {ApplyScaling( *((Matrix3*)val), *((ScaleValue*)delta) );}
void MultiplyValue(void *val, float m) {*((ScaleValue*)val) *= m;}
};
class ScaleNoiseClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading) { return new ScaleNoiseControl(); }
const TCHAR * ClassName() { return SCALENOISE_CONTROL_CNAME; }
SClass_ID SuperClassID() { return CTRL_SCALE_CLASS_ID; }
Class_ID ClassID() { return Class_ID(SCALENOISE_CONTROL_CLASS_ID,0);}
const TCHAR* Category() { return _T(""); }
};
static ScaleNoiseClassDesc scaleNoiseCD;
ClassDesc* GetScaleNoiseDesc() {return &scaleNoiseCD;}
//-----------------------------------------------------------------------------
class RangeRestore : public RestoreObj {
public:
BaseNoiseControl *cont;
Interval ur, rr;
RangeRestore(BaseNoiseControl *c)
{
cont = c;
ur = cont->range;
}
void Restore(int isUndo)
{
rr = cont->range;
cont->range = ur;
cont->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void Redo()
{
cont->range = rr;
cont->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void EndHold()
{
cont->ClearAFlag(A_HELD);
}
TSTR Description() { return TSTR(_T("Noise control range")); }
};
//-----------------------------------------------------------------
//
// UI
static LRESULT CALLBACK NoiseGraphWinProc(
HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static void InitNoiseGraph(HINSTANCE hInst)
{
static BOOL init = FALSE;
if (init) return;
else init = TRUE;
WNDCLASS wc;
wc.style = 0;
wc.hInstance = hInst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.lpfnWndProc = NoiseGraphWinProc;
wc.lpszClassName = _T("NoiseGraph");
RegisterClass(&wc);
}
#define STEPSIZE 4
#define GRAPH_TIMESCALE 20
static void DrawNoiseGraph(BaseNoiseControl *cont,HWND hWnd,HDC hdc)
{
Rect rect, orect;
GetClientRect(hWnd,&rect);
orect = rect;
float v, fy;
int mid = rect.h()/2;
rect.top += 5;
rect.bottom -= 5;
TimeValue end = rect.right * GRAPH_TIMESCALE;
SelectObject(hdc,CreatePen(PS_DOT,0,GetSysColor(COLOR_BTNFACE)));
MoveToEx(hdc,0,mid,NULL);
LineTo(hdc,rect.right,mid);
MoveToEx(hdc,cont->rampin / GRAPH_TIMESCALE,0,NULL);
LineTo(hdc,cont->rampin / GRAPH_TIMESCALE,rect.bottom);
MoveToEx(hdc,rect.right - cont->rampout / GRAPH_TIMESCALE,0,NULL);
LineTo(hdc,rect.right - cont->rampout / GRAPH_TIMESCALE,rect.bottom);
DeleteObject(SelectObject(hdc,GetStockObject(BLACK_PEN)));
for (int x = 0; x < rect.right + STEPSIZE; x += STEPSIZE) {
int t = x*GRAPH_TIMESCALE;
float ramp = 1.0f;
if (t<cont->rampin) {
float u = float(t)/float(cont->rampin);
ramp *= u*u * (3.0f-2.0f*u);
}
if (t>end-cont->rampout) {
float u = float(end-t)/float(cont->rampout);
ramp *= u*u * (3.0f-2.0f*u);
}
v = float(t) * float(0.005) * cont->frequency + Perm(cont->seed);
if (cont->fractal) {
fy = (float)fBm1(v, 1.0f-cont->roughness, 2.0f, 6 /*octaves*/);
} else {
fy = noise1(v);
}
fy *= ramp;
if (!x) {
MoveToEx(hdc,0,mid + int((rect.h()) * fy),NULL);
} else {
LineTo(hdc,x,mid + int((rect.h()) * fy));
}
}
WhiteRect3D(hdc,orect,TRUE);
}
static LRESULT CALLBACK NoiseGraphWinProc(
HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
BaseNoiseControl *cont = (BaseNoiseControl*)GetWindowLong(hWnd,GWL_USERDATA);
if (!cont) return DefWindowProc(hWnd,msg,wParam,lParam);
switch (msg) {
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd,&ps);
DrawNoiseGraph(cont,hWnd,hdc);
EndPaint(hWnd,&ps);
break;
}
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}
return 0;
}
//--------------------------------------------------------------
static BOOL CALLBACK NoiseDlgProc(
HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static int strengthSpinID[] = {IDC_NOISE_XSTRENGTHSPIN,IDC_NOISE_YSTRENGTHSPIN,IDC_NOISE_ZSTRENGTHSPIN};
static int strengthEditID[] = {IDC_NOISE_XSTRENGTH,IDC_NOISE_YSTRENGTH,IDC_NOISE_ZSTRENGTH};
static int strengthLabelID[] = {IDC_NOISE_XSTRENGTHLABEL,IDC_NOISE_YSTRENGTHLABEL,IDC_NOISE_ZSTRENGTHLABEL};
static int limID[] = {IDC_NOISE_XLIM0,IDC_NOISE_YLIM0,IDC_NOISE_ZLIM0};
#define NOISEDLG_CLASS_ID 0xaab659c4
class NoiseCtrlWindow {
public:
HWND hWnd;
HWND hParent;
Control *cont;
NoiseCtrlWindow() {assert(0);}
NoiseCtrlWindow(HWND hWnd,HWND hParent,Control *cont)
{this->hWnd=hWnd; this->hParent=hParent; this->cont=cont;}
};
static Tab<NoiseCtrlWindow> noiseCtrlWindows;
static void RegisterNoiseCtrlWindow(HWND hWnd, HWND hParent, Control *cont)
{
NoiseCtrlWindow rec(hWnd,hParent,cont);
noiseCtrlWindows.Append(1,&rec);
}
static void UnRegisterNoiseCtrlWindow(HWND hWnd)
{
for (int i=0; i<noiseCtrlWindows.Count(); i++) {
if (hWnd==noiseCtrlWindows[i].hWnd) {
noiseCtrlWindows.Delete(i,1);
return;
}
}
}
static HWND FindOpenNoiseCtrlWindow(HWND hParent,Control *cont)
{
for (int i=0; i<noiseCtrlWindows.Count(); i++) {
if (hParent == noiseCtrlWindows[i].hParent &&
cont == noiseCtrlWindows[i].cont) {
return noiseCtrlWindows[i].hWnd;
}
}
return NULL;
}
class NoiseDlg : public ReferenceMaker, public TimeChangeCallback {
public:
BaseNoiseControl *cont;
ParamDimensionBase *dim;
IObjParam *ip;
HWND hWnd;
BOOL valid;
int elems;
ISpinnerControl *iStrength[MAX_ELEMS];
ISpinnerControl *iSeed, *iFreq, *iRough, *iRampIn, *iRampOut;
NoiseDlg(
BaseNoiseControl *cont,
ParamDimensionBase *dim,
TCHAR *pname,
IObjParam *ip,
HWND hParent);
~NoiseDlg();
Class_ID ClassID() {return Class_ID(NOISEDLG_CLASS_ID,0);}
SClass_ID SuperClassID() {return REF_MAKER_CLASS_ID;}
void MaybeCloseWindow();
void TimeChanged(TimeValue t) {Invalidate();}
void Invalidate();
void Update();
void SetupUI(HWND hWnd);
void Change(BOOL redraw=FALSE);
void WMCommand(int id, int notify, HWND hCtrl);
void SpinnerChange(int id,BOOL drag);
void SpinnerStart(int id);
void SpinnerEnd(int id,BOOL cancel);
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
PartID& partID, RefMessage message);
int NumRefs() {return 1;}
RefTargetHandle GetReference(int i) {return cont;}
void SetReference(int i, RefTargetHandle rtarg) {cont=(BaseNoiseControl*)rtarg;}
};
NoiseDlg::NoiseDlg(
BaseNoiseControl *cont,
ParamDimensionBase *dim,
TCHAR *pname,
IObjParam *ip,
HWND hParent)
{
InitNoiseGraph(hInstance);
this->cont = cont;
this->ip = ip;
this->dim = dim;
valid = FALSE;
elems = cont->Elems();
theHold.Suspend();
MakeRefByID(FOREVER,0,cont);
theHold.Resume();
hWnd = CreateDialogParam(
hInstance,
MAKEINTRESOURCE(IDD_NOISEPARAMS),
hParent,
NoiseDlgProc,
(LPARAM)this);
TSTR title = TSTR(GetString(IDS_RB_NOISECONTROLTITLE)) + TSTR(pname);
SetWindowText(hWnd,title);
ip->RegisterTimeChangeCallback(this);
}
NoiseDlg::~NoiseDlg()
{
UnRegisterNoiseCtrlWindow(hWnd);
ip->UnRegisterTimeChangeCallback(this);
theHold.Suspend();
DeleteAllRefsFromMe();
theHold.Resume();
ReleaseISpinner(iSeed);
ReleaseISpinner(iFreq);
ReleaseISpinner(iRough);
ReleaseISpinner(iRampIn);
ReleaseISpinner(iRampOut);
for (int i=0; i<elems; i++) {
ReleaseISpinner(iStrength[i]);
}
}
void NoiseDlg::Invalidate()
{
valid = FALSE;
InvalidateRect(hWnd,NULL,FALSE);
InvalidateRect(GetDlgItem(hWnd,IDC_NOISE_GRAPH),NULL,FALSE);
}
void NoiseDlg::Update()
{
if (!valid && hWnd) {
float strength[MAX_ELEMS];
cont->GetStrength(ip->GetTime(),strength);
for (int i=0; i<elems; i++) {
iStrength[i]->SetValue(dim->Convert(strength[i]),FALSE);
CheckDlgButton(hWnd,limID[i],cont->lim[i]);
}
iSeed->SetValue(cont->seed,FALSE);
iFreq->SetValue(cont->frequency,FALSE);
iRough->SetValue(cont->roughness,FALSE);
iRampIn->SetValue(cont->rampin,FALSE);
iRampOut->SetValue(cont->rampout,FALSE);
if (cont->fractal) {
CheckDlgButton(hWnd,IDC_NOISE_FRACTAL,TRUE);
EnableWindow(GetDlgItem(hWnd,IDC_NOISE_ROUGHLABEL),TRUE);
EnableWindow(GetDlgItem(hWnd,IDC_NOISE_ROUGHSPIN),TRUE);
} else {
CheckDlgButton(hWnd,IDC_NOISE_FRACTAL,FALSE);
EnableWindow(GetDlgItem(hWnd,IDC_NOISE_ROUGHLABEL),FALSE);
EnableWindow(GetDlgItem(hWnd,IDC_NOISE_ROUGHSPIN),FALSE);
}
valid = TRUE;
}
}
void NoiseDlg::SetupUI(HWND hWnd)
{
this->hWnd = hWnd;
for (int i=0; i<elems; i++) {
iStrength[i] = GetISpinner(GetDlgItem(hWnd,strengthSpinID[i]));
iStrength[i]->SetLimits(-9999999,9999999,FALSE);
iStrength[i]->SetAutoScale();
iStrength[i]->LinkToEdit(GetDlgItem(hWnd,strengthEditID[i]),EDITTYPE_FLOAT);
}
for ( ; i< MAX_ELEMS; i++) {
ShowWindow(GetDlgItem(hWnd,strengthSpinID[i]),SW_HIDE);
ShowWindow(GetDlgItem(hWnd,strengthEditID[i]),SW_HIDE);
ShowWindow(GetDlgItem(hWnd,strengthLabelID[i]),SW_HIDE);
ShowWindow(GetDlgItem(hWnd,limID[i]),SW_HIDE);
}
iSeed = GetISpinner(GetDlgItem(hWnd,IDC_NOISE_SEEDSPIN));
iSeed->SetLimits(0,9999999,FALSE);
iSeed->SetScale(0.1f);
iSeed->LinkToEdit(GetDlgItem(hWnd,IDC_NOISE_SEED),EDITTYPE_INT);
iFreq = GetISpinner(GetDlgItem(hWnd,IDC_NOISE_FREQSPIN));
iFreq->SetLimits(0.001f,10.0f,FALSE);
iFreq->SetScale(0.005f);
iFreq->LinkToEdit(GetDlgItem(hWnd,IDC_NOISE_FREQ),EDITTYPE_FLOAT);
iRough = GetISpinner(GetDlgItem(hWnd,IDC_NOISE_ROUGHSPIN));
iRough->SetLimits(0.0f,1.0f,FALSE);
iRough->SetScale(0.005f);
iRough->LinkToEdit(GetDlgItem(hWnd,IDC_NOISE_ROUGH),EDITTYPE_FLOAT);
iRampIn = GetISpinner(GetDlgItem(hWnd,IDC_NOISE_RAMPINSPIN));
iRampIn->SetLimits(0,TIME_PosInfinity,FALSE);
iRampIn->SetScale(10.0f);
iRampIn->LinkToEdit(GetDlgItem(hWnd,IDC_NOISE_RAMPIN),EDITTYPE_TIME);
iRampOut = GetISpinner(GetDlgItem(hWnd,IDC_NOISE_RAMPOUTSPIN));
iRampOut->SetLimits(0,TIME_PosInfinity,FALSE);
iRampOut->SetScale(10.0f);
iRampOut->LinkToEdit(GetDlgItem(hWnd,IDC_NOISE_RAMPOUT),EDITTYPE_TIME);
if (elems==1) {
SetWindowText(GetDlgItem(hWnd,IDC_NOISE_XSTRENGTHLABEL),
GetString(IDS_RB_STRENGTH));
}
SetWindowLong(GetDlgItem(hWnd,IDC_NOISE_GRAPH),GWL_USERDATA,(LONG)cont);
valid = FALSE;
Update();
}
void NoiseDlg::WMCommand(int id, int notify, HWND hCtrl)
{
switch (id) {
case IDC_NOISE_FRACTAL:
cont->fractal = IsDlgButtonChecked(hWnd,id);
Change(TRUE);
break;
case IDC_NOISE_XLIM0:
cont->lim[0] = IsDlgButtonChecked(hWnd,id);
Change(TRUE);
break;
case IDC_NOISE_YLIM0:
cont->lim[1] = IsDlgButtonChecked(hWnd,id);
Change(TRUE);
break;
case IDC_NOISE_ZLIM0:
cont->lim[2] = IsDlgButtonChecked(hWnd,id);
Change(TRUE);
break;
}
}
void NoiseDlg::SpinnerChange(int id,BOOL drag)
{
float strength[MAX_ELEMS];
BOOL strengthChange = FALSE;
if (!drag) {
SpinnerStart(id);
}
if (id==IDC_NOISE_XSTRENGTHSPIN ||
id==IDC_NOISE_YSTRENGTHSPIN ||
id==IDC_NOISE_ZSTRENGTHSPIN) {
cont->GetStrength(ip->GetTime(),strength);
}
switch (id) {
case IDC_NOISE_XSTRENGTHSPIN:
strength[0] = dim->UnConvert(iStrength[0]->GetFVal());
strengthChange = TRUE;
Change(1);
break;
case IDC_NOISE_YSTRENGTHSPIN:
strength[1] = dim->UnConvert(iStrength[1]->GetFVal());
strengthChange = TRUE;
Change(1);
break;
case IDC_NOISE_ZSTRENGTHSPIN:
strength[2] = dim->UnConvert(iStrength[2]->GetFVal());
strengthChange = TRUE;
Change(1);
break;
case IDC_NOISE_SEEDSPIN:
cont->seed = iSeed->GetIVal();
Change(1);
break;
case IDC_NOISE_FREQSPIN:
cont->frequency = iFreq->GetFVal();
Change(1);
break;
case IDC_NOISE_ROUGHSPIN:
cont->roughness = iRough->GetFVal();
Change(1);
break;
case IDC_NOISE_RAMPINSPIN:
cont->rampin = iRampIn->GetIVal();
Change(1);
break;
case IDC_NOISE_RAMPOUTSPIN:
cont->rampout = iRampOut->GetIVal();
Change(1);
break;
}
if (strengthChange) {
cont->cont->SetValue(ip->GetTime(),strength);
}
}
void NoiseDlg::SpinnerStart(int id)
{
switch (id) {
case IDC_NOISE_XSTRENGTHSPIN:
case IDC_NOISE_YSTRENGTHSPIN:
case IDC_NOISE_ZSTRENGTHSPIN:
theHold.Begin();
break;
}
}
void NoiseDlg::SpinnerEnd(int id,BOOL cancel)
{
switch (id) {
case IDC_NOISE_XSTRENGTH:
case IDC_NOISE_YSTRENGTH:
case IDC_NOISE_ZSTRENGTH:
case IDC_NOISE_XSTRENGTHSPIN:
case IDC_NOISE_YSTRENGTHSPIN:
case IDC_NOISE_ZSTRENGTHSPIN:
if (cancel) {
theHold.Cancel();
} else {
theHold.Accept(GetString(IDS_RB_CHANGESTRENGTH));
}
break;
}
ip->RedrawViews(ip->GetTime());
}
void NoiseDlg::Change(BOOL redraw)
{
InvalidateRect(GetDlgItem(hWnd,IDC_NOISE_GRAPH),NULL,TRUE);
cont->NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
UpdateWindow(GetDlgItem(hWnd,IDC_NOISE_GRAPH));
UpdateWindow(GetParent(hWnd));
if (redraw) ip->RedrawViews(ip->GetTime());
}
class CheckForNonNoiseDlg : public DependentEnumProc {
public:
BOOL non;
ReferenceMaker *me;
CheckForNonNoiseDlg(ReferenceMaker *m) {non = FALSE;me = m;}
int proc(ReferenceMaker *rmaker) {
if (rmaker==me) return 0;
if (rmaker->SuperClassID()!=REF_MAKER_CLASS_ID &&
rmaker->ClassID()!=Class_ID(NOISEDLG_CLASS_ID,0)) {
non = TRUE;
return 1;
}
return 0;
}
};
void NoiseDlg::MaybeCloseWindow()
{
CheckForNonNoiseDlg check(cont);
cont->EnumDependents(&check);
if (!check.non) {
PostMessage(hWnd,WM_CLOSE,0,0);
}
}
RefResult NoiseDlg::NotifyRefChanged(
Interval changeInt,
RefTargetHandle hTarget,
PartID& partID,
RefMessage message)
{
switch (message) {
case REFMSG_CHANGE:
Invalidate();
break;
case REFMSG_REF_DELETED:
MaybeCloseWindow();
break;
}
return REF_SUCCEED;
}
static BOOL CALLBACK NoiseDlgProc(
HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
NoiseDlg *dlg = (NoiseDlg*)GetWindowLong(hWnd,GWL_USERDATA);
switch (msg) {
case WM_INITDIALOG:
dlg = (NoiseDlg*)lParam;
SetWindowLong(hWnd,GWL_USERDATA,lParam);
dlg->SetupUI(hWnd);
break;
case CC_SPINNER_BUTTONDOWN:
dlg->SpinnerStart(LOWORD(wParam));
break;
case CC_SPINNER_CHANGE:
dlg->SpinnerChange(LOWORD(wParam),HIWORD(wParam));
break;
case WM_CUSTEDIT_ENTER:
case CC_SPINNER_BUTTONUP:
dlg->SpinnerEnd(LOWORD(wParam),!HIWORD(wParam));
break;
case WM_COMMAND:
dlg->WMCommand(LOWORD(wParam),HIWORD(wParam),(HWND)lParam);
break;
case WM_PAINT:
dlg->Update();
return 0;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
delete dlg;
break;
default:
return FALSE;
}
return TRUE;
}
void BaseNoiseControl::EditTrackParams(
TimeValue t,
ParamDimensionBase *dim,
TCHAR *pname,
HWND hParent,
IObjParam *ip,
DWORD flags)
{
HWND hCur = FindOpenNoiseCtrlWindow(hParent,this);
if (hCur) {
SetForegroundWindow(hCur);
return;
}
NoiseDlg *dlg = new NoiseDlg(this,dim,pname,ip,hParent);
RegisterNoiseCtrlWindow(dlg->hWnd,hParent,this);
}
//------------------------------------------------------------
BaseNoiseControl::BaseNoiseControl()
{
for (int i=0; i<MAX_ELEMS; i++) {
//strength[i] = 50.0f;
lim[i] = FALSE;
}
fractal = TRUE;
roughness = 0.0f;
frequency = 0.5f;
seed = 0;
rampin = rampout = 0;
range = Interval(GetAnimStart(),GetAnimEnd());
}
BaseNoiseControl& BaseNoiseControl::operator=(const BaseNoiseControl& from)
{
ReplaceReference(Control::NumRefs(),from.cont);
for (int i=0; i<MAX_ELEMS; i++) {
//strength[i] = from.strength[i];
lim[i] = from.lim[i];
}
fractal = from.fractal;
roughness = from.roughness;
frequency = from.frequency;
seed = from.seed;
range = from.range;
rampin = from.rampin;
rampout = from.rampout;
return *this;
}
int BaseNoiseControl::NumSubs()
{
return Control::NumSubs()+1;
}
Animatable* BaseNoiseControl::SubAnim(int i)
{
if (i<Control::NumSubs()) return Control::SubAnim(i);
return cont;
}
TSTR BaseNoiseControl::SubAnimName(int i)
{
if (i<Control::NumSubs())
return Control::SubAnimName(i);
return GetString(IDS_RB_NOISESTRENGTH);
}
BOOL BaseNoiseControl::AssignController(Animatable *control,int subAnim)
{
ReplaceReference(Control::NumRefs(),(Control*)control);
return TRUE;
}
int BaseNoiseControl::SubNumToRefNum(int subNum)
{
return Control::NumRefs();
}
int BaseNoiseControl::NumRefs()
{
return Control::NumRefs()+1;
}
RefTargetHandle BaseNoiseControl::GetReference(int i)
{
if (i<Control::NumRefs()) return Control::GetReference(i);
return cont;
}
void BaseNoiseControl::SetReference(int i, RefTargetHandle rtarg)
{
if (i<Control::NumRefs()) Control::SetReference(i,rtarg);
else cont = (Control*)rtarg;
}
extern float noise1(float arg);
float BaseNoiseControl::NoiseAtTime(TimeValue t,int s,int index)
{
float ramp = 1.0f, res;
// Limit to in range
if (t<range.Start()) t = range.Start();
if (t>range.End()) t = range.End();
// Compute ramping
if (t<range.Start()+rampin) {
float u = float(t-range.Start())/float(rampin);
ramp *= u*u * (3.0f-2.0f*u);
}
if (t>range.End()-rampout) {
float u = float(range.End()-t)/float(rampout);
ramp *= u*u * (3.0f-2.0f*u);
}
// Compute noise
float v = float(t) * float(0.005) * frequency + Perm(s);
if (fractal) {
res = (float)fBm1(v, 1.0f-roughness, 2.0f, 6 /*octaves*/);
} else {
res = noise1(v);
}
if (lim[index]) {
res = res+0.5f;
}
return res * ramp;
}
void BaseNoiseControl::HoldRange()
{
if (theHold.Holding() && !TestAFlag(A_HELD)) {
SetAFlag(A_HELD);
theHold.Put(new RangeRestore(this));
}
}
void BaseNoiseControl::EditTimeRange(Interval range,DWORD flags)
{
if (!(flags&EDITRANGE_LINKTOKEYS)) {
HoldRange();
this->range = range;
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
}
void BaseNoiseControl::MapKeys(TimeMap *map,DWORD flags)
{
if (flags&TRACK_MAPRANGE) {
HoldRange();
TimeValue t0 = map->map(range.Start());
TimeValue t1 = map->map(range.End());
range.Set(t0,t1);
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
}
#define XSTRENGTH_CHUNK 0x0100
#define YSTRENGTH_CHUNK 0x0101
#define ZSTRENGTH_CHUNK 0x0102
#define FREQUENCY_CHUNK 0x0103
#define ROUGHNESS_CHUNK 0x0104
#define SEED_CHUNK 0x0105
#define FRACTAL_CHUNK 0x0106
#define RANGE_CHUNK 0x0107
#define RAMPIN_CHUNK 0x0108
#define RAMPOUT_CHUNK 0x0109
#define XLIM_CHUNK 0x0110
#define YLIM_CHUNK 0x0111
#define ZLIM_CHUNK 0x0112
IOResult BaseNoiseControl::Save(ISave *isave)
{
ULONG nb;
for (int i=0; i<MAX_ELEMS; i++) {
//isave->BeginChunk(XSTRENGTH_CHUNK+i);
//isave->Write(&strength[i],sizeof(strength[i]),&nb);
//isave->EndChunk();
isave->BeginChunk(XLIM_CHUNK+i);
isave->Write(&lim[i],sizeof(lim[i]),&nb);
isave->EndChunk();
}
isave->BeginChunk(FREQUENCY_CHUNK);
isave->Write(&frequency,sizeof(frequency),&nb);
isave->EndChunk();
isave->BeginChunk(ROUGHNESS_CHUNK);
isave->Write(&roughness,sizeof(roughness),&nb);
isave->EndChunk();
isave->BeginChunk(SEED_CHUNK);
isave->Write(&seed,sizeof(seed),&nb);
isave->EndChunk();
isave->BeginChunk(FRACTAL_CHUNK);
isave->Write(&fractal,sizeof(fractal),&nb);
isave->EndChunk();
isave->BeginChunk(RANGE_CHUNK);
isave->Write(&range,sizeof(range),&nb);
isave->EndChunk();
isave->BeginChunk(RAMPIN_CHUNK);
isave->Write(&rampin,sizeof(rampin),&nb);
isave->EndChunk();
isave->BeginChunk(RAMPOUT_CHUNK);
isave->Write(&rampout,sizeof(rampout),&nb);
isave->EndChunk();
return IO_OK;
}
IOResult BaseNoiseControl::Load(ILoad *iload)
{
float strength[MAX_ELEMS];
BOOL strengthRead=FALSE;
ULONG nb;
IOResult res = IO_OK;
while (IO_OK==(res=iload->OpenChunk())) {
switch (iload->CurChunkID()) {
case XSTRENGTH_CHUNK:
res=iload->Read(&strength[0],sizeof(strength[0]),&nb);
strengthRead = TRUE;
break;
case YSTRENGTH_CHUNK:
res=iload->Read(&strength[1],sizeof(strength[1]),&nb);
strengthRead = TRUE;
break;
case ZSTRENGTH_CHUNK:
res=iload->Read(&strength[2],sizeof(strength[2]),&nb);
strengthRead = TRUE;
break;
case XLIM_CHUNK:
res=iload->Read(&lim[0],sizeof(lim[0]),&nb);
break;
case YLIM_CHUNK:
res=iload->Read(&lim[1],sizeof(lim[1]),&nb);
break;
case ZLIM_CHUNK:
res=iload->Read(&lim[2],sizeof(lim[2]),&nb);
break;
case FREQUENCY_CHUNK:
res=iload->Read(&frequency,sizeof(frequency),&nb);
break;
case ROUGHNESS_CHUNK:
res=iload->Read(&roughness,sizeof(roughness),&nb);
break;
case SEED_CHUNK:
res=iload->Read(&seed,sizeof(seed),&nb);
break;
case FRACTAL_CHUNK:
res=iload->Read(&fractal,sizeof(fractal),&nb);
break;
case RANGE_CHUNK:
res=iload->Read(&range,sizeof(range),&nb);
break;
case RAMPIN_CHUNK:
res=iload->Read(&rampin,sizeof(rampin),&nb);
break;
case RAMPOUT_CHUNK:
res=iload->Read(&rampout,sizeof(rampout),&nb);
break;
}
iload->CloseChunk();
if (res!=IO_OK) return res;
}
if (strengthRead) {
cont->SetValue(0,strength);
}
return IO_OK;
}
void BaseNoiseControl::SetSeed(int seed)
{
this->seed = seed;
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BaseNoiseControl::SetFrequency(float f)
{
frequency = f;
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BaseNoiseControl::SetFractal(BOOL f)
{
fractal = f;
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BaseNoiseControl::SetRoughness(float f)
{
roughness = f;
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BaseNoiseControl::SetRampIn(TimeValue in)
{
rampin = in;
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BaseNoiseControl::SetRampOut(TimeValue out)
{
rampout = out;
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BaseNoiseControl::SetPositiveOnly(int which,BOOL onOff)
{
lim[which] = onOff;
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BaseNoiseControl::SetStrengthController(Control *c)
{
ReplaceReference(Control::NumRefs(),c);
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
//--------------------------------------------------------------------
RefTargetHandle FloatNoiseControl::Clone(RemapDir& remap)
{
// make a new noise controller and give it our param values.
FloatNoiseControl *cont = new FloatNoiseControl;
*cont = *this;
// Clone the strength controller
cont->ReplaceReference(Control::NumRefs(),remap.CloneRef(cont->cont));
CloneControl(cont,remap);
return cont;
}
void FloatNoiseControl::GetValueLocalTime(
TimeValue t, void *val, Interval &valid, GetSetMethod method)
{
float strength;
GetStrength(t,&strength);
// This controller is always changing.
valid.SetInstant(t);
*((float*)val) = NoiseAtTime(t,seed,0) * strength;
}
void FloatNoiseControl::Extrapolate(
Interval range,TimeValue t,void *val,Interval &valid,int type)
{
float val0, val1, val2, res;
switch (type) {
case ORT_LINEAR:
if (t<range.Start()) {
GetValueLocalTime(range.Start(),&val0,valid);
GetValueLocalTime(range.Start()+1,&val1,valid);
res = LinearExtrapolate(range.Start(),t,val0,val1,val0);
} else {
GetValueLocalTime(range.End()-1,&val0,valid);
GetValueLocalTime(range.End(),&val1,valid);
res = LinearExtrapolate(range.End(),t,val0,val1,val1);
}
break;
case ORT_IDENTITY:
if (t<range.Start()) {
GetValueLocalTime(range.Start(),&val0,valid);
res = IdentityExtrapolate(range.Start(),t,val0);
} else {
GetValueLocalTime(range.End(),&val0,valid);
res = IdentityExtrapolate(range.End(),t,val0);
}
break;
case ORT_RELATIVE_REPEAT:
GetValueLocalTime(range.Start(),&val0,valid);
GetValueLocalTime(range.End(),&val1,valid);
GetValueLocalTime(CycleTime(range,t),&val2,valid);
res = RepeatExtrapolate(range,t,val0,val1,val2);
break;
}
valid.Set(t,t);
*((float*)val) = res;
}
//--------------------------------------------------------------------------
RefTargetHandle PositionNoiseControl::Clone(RemapDir& remap)
{
// make a new noise controller and give it our param values.
PositionNoiseControl *cont = new PositionNoiseControl;
*cont = *this;
// Clone the strength controller
cont->ReplaceReference(Control::NumRefs(),remap.CloneRef(cont->cont));
CloneControl(cont,remap);
return cont;
}
void PositionNoiseControl::GetValueLocalTime(
TimeValue t, void *val, Interval &valid, GetSetMethod method)
{
float strength[3];
GetStrength(t,strength);
// This controller is always changing.
valid.SetInstant(t);
*((Point3*)val) = Point3(
NoiseAtTime(t,seed,0) * strength[0],
NoiseAtTime(t,seed+1,1) * strength[1],
NoiseAtTime(t,seed+2,2) * strength[2] );
}
void PositionNoiseControl::Extrapolate(
Interval range,TimeValue t,void *val,Interval &valid,int type)
{
Point3 val0, val1, val2, res;
switch (type) {
case ORT_LINEAR:
if (t<range.Start()) {
GetValueLocalTime(range.Start(),&val0,valid);
GetValueLocalTime(range.Start()+1,&val1,valid);
res = LinearExtrapolate(range.Start(),t,val0,val1,val0);
} else {
GetValueLocalTime(range.End()-1,&val0,valid);
GetValueLocalTime(range.End(),&val1,valid);
res = LinearExtrapolate(range.End(),t,val0,val1,val1);
}
break;
case ORT_IDENTITY:
if (t<range.Start()) {
GetValueLocalTime(range.Start(),&val0,valid);
res = IdentityExtrapolate(range.Start(),t,val0);
} else {
GetValueLocalTime(range.End(),&val0,valid);
res = IdentityExtrapolate(range.End(),t,val0);
}
break;
case ORT_RELATIVE_REPEAT:
GetValueLocalTime(range.Start(),&val0,valid);
GetValueLocalTime(range.End(),&val1,valid);
GetValueLocalTime(CycleTime(range,t),&val2,valid);
res = RepeatExtrapolate(range,t,val0,val1,val2);
break;
}
valid.Set(t,t);
*((Point3*)val) = res;
}
//--------------------------------------------------------------------------
RefTargetHandle Point3NoiseControl::Clone(RemapDir& remap)
{
// make a new noise controller and give it our param values.
Point3NoiseControl *cont = new Point3NoiseControl;
*cont = *this;
// Clone the strength controller
cont->ReplaceReference(Control::NumRefs(),remap.CloneRef(cont->cont));
CloneControl(cont,remap);
return cont;
}
void Point3NoiseControl::GetValueLocalTime(
TimeValue t, void *val, Interval &valid, GetSetMethod method)
{
float strength[3];
GetStrength(t,strength);
// This controller is always changing.
valid.SetInstant(t);
*((Point3*)val) = Point3(
NoiseAtTime(t,seed,0) * strength[0],
NoiseAtTime(t,seed+1,1) * strength[1],
NoiseAtTime(t,seed+2,2) * strength[2] );
}
void Point3NoiseControl::Extrapolate(
Interval range,TimeValue t,void *val,Interval &valid,int type)
{
Point3 val0, val1, val2, res;
switch (type) {
case ORT_LINEAR:
if (t<range.Start()) {
GetValueLocalTime(range.Start(),&val0,valid);
GetValueLocalTime(range.Start()+1,&val1,valid);
res = LinearExtrapolate(range.Start(),t,val0,val1,val0);
} else {
GetValueLocalTime(range.End()-1,&val0,valid);
GetValueLocalTime(range.End(),&val1,valid);
res = LinearExtrapolate(range.End(),t,val0,val1,val1);
}
break;
case ORT_IDENTITY:
if (t<range.Start()) {
GetValueLocalTime(range.Start(),&val0,valid);
res = IdentityExtrapolate(range.Start(),t,val0);
} else {
GetValueLocalTime(range.End(),&val0,valid);
res = IdentityExtrapolate(range.End(),t,val0);
}
break;
case ORT_RELATIVE_REPEAT:
GetValueLocalTime(range.Start(),&val0,valid);
GetValueLocalTime(range.End(),&val1,valid);
GetValueLocalTime(CycleTime(range,t),&val2,valid);
res = RepeatExtrapolate(range,t,val0,val1,val2);
break;
}
valid.Set(t,t);
*((Point3*)val) = res;
}
//--------------------------------------------------------------------------
RefTargetHandle RotationNoiseControl::Clone(RemapDir& remap)
{
// make a new noise controller and give it our param values.
RotationNoiseControl *cont = new RotationNoiseControl;
*cont = *this;
// Clone the strength controller
cont->ReplaceReference(Control::NumRefs(),remap.CloneRef(cont->cont));
CloneControl(cont,remap);
return cont;
}
void RotationNoiseControl::GetValueLocalTime(
TimeValue t, void *val, Interval &valid, GetSetMethod method)
{
float strength[3];
GetStrength(t,strength);
// This controller is always changing.
valid.SetInstant(t);
float ang[3];
ang[0] = NoiseAtTime(t,seed,0) * strength[0];
ang[1] = NoiseAtTime(t,seed+1,1) * strength[1];
ang[2] = NoiseAtTime(t,seed+2,2) * strength[2];
EulerToQuat(ang,*((Quat*)val));
}
void RotationNoiseControl::Extrapolate(
Interval range,TimeValue t,void *val,Interval &valid,int type)
{
Quat val0, val1, val2, res;
switch (type) {
case ORT_LINEAR:
if (t<range.Start()) {
GetValueLocalTime(range.Start(),&val0,valid);
GetValueLocalTime(range.Start()+1,&val1,valid);
res = LinearExtrapolate(range.Start(),t,val0,val1,val0);
} else {
GetValueLocalTime(range.End()-1,&val0,valid);
GetValueLocalTime(range.End(),&val1,valid);
res = LinearExtrapolate(range.End(),t,val0,val1,val1);
}
break;
case ORT_IDENTITY:
if (t<range.Start()) {
GetValueLocalTime(range.Start(),&val0,valid);
res = IdentityExtrapolate(range.Start(),t,val0);
} else {
GetValueLocalTime(range.End(),&val0,valid);
res = IdentityExtrapolate(range.End(),t,val0);
}
break;
case ORT_RELATIVE_REPEAT:
GetValueLocalTime(range.Start(),&val0,valid);
GetValueLocalTime(range.End(),&val1,valid);
GetValueLocalTime(CycleTime(range,t),&val2,valid);
res = RepeatExtrapolate(range,t,val0,val1,val2);
break;
}
valid.Set(t,t);
*((Quat*)val) = res;
}
//--------------------------------------------------------------------------
RefTargetHandle ScaleNoiseControl::Clone(RemapDir& remap)
{
// make a new noise controller and give it our param values.
ScaleNoiseControl *cont = new ScaleNoiseControl;
*cont = *this;
// Clone the strength controller
cont->ReplaceReference(Control::NumRefs(),remap.CloneRef(cont->cont));
CloneControl(cont,remap);
return cont;
}
void ScaleNoiseControl::GetValueLocalTime(
TimeValue t, void *val, Interval &valid, GetSetMethod method)
{
float strength[3];
GetStrength(t,strength);
// This controller is always changing.
valid.SetInstant(t);
*((ScaleValue*)val) = ScaleValue(
Point3(
1.0f + NoiseAtTime(t,seed,0) * strength[0],
1.0f + NoiseAtTime(t,seed+1,1) * strength[1],
1.0f + NoiseAtTime(t,seed+2,2) * strength[2] ),
Quat(0.0,0.0,0.0,1.0));
}
void ScaleNoiseControl::Extrapolate(
Interval range,TimeValue t,void *val,Interval &valid,int type)
{
ScaleValue val0, val1, val2, res;
switch (type) {
case ORT_LINEAR:
if (t<range.Start()) {
GetValueLocalTime(range.Start(),&val0,valid);
GetValueLocalTime(range.Start()+1,&val1,valid);
res = LinearExtrapolate(range.Start(),t,val0,val1,val0);
} else {
GetValueLocalTime(range.End()-1,&val0,valid);
GetValueLocalTime(range.End(),&val1,valid);
res = LinearExtrapolate(range.End(),t,val0,val1,val1);
}
break;
case ORT_IDENTITY:
if (t<range.Start()) {
GetValueLocalTime(range.Start(),&val0,valid);
res = IdentityExtrapolate(range.Start(),t,val0);
} else {
GetValueLocalTime(range.End(),&val0,valid);
res = IdentityExtrapolate(range.End(),t,val0);
}
break;
case ORT_RELATIVE_REPEAT:
GetValueLocalTime(range.Start(),&val0,valid);
GetValueLocalTime(range.End(),&val1,valid);
GetValueLocalTime(CycleTime(range,t),&val2,valid);
res = RepeatExtrapolate(range,t,val0,val1,val2);
break;
}
valid.Set(t,t);
*((ScaleValue*)val) = res;
}