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.
This commit is contained in:
Cyd
2026-06-24 21:28:16 -05:00
commit 2b8ca921cb
66341 changed files with 7923174 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,926 @@
#if 0
/**********************************************************************
*<
FILE: boolctrl.cpp
DESCRIPTION: A boolean controller
CREATED BY: Rolf Berteig
HISTORY: 11/18/96
*> Copyright (c) 1996, All Rights Reserved.
**********************************************************************/
#include "ctrl.h"
#include "units.h"
#include "exprlib.h"
#define BOOL_CONTROL_CLASS_ID Class_ID(0x984b8d27,0x938f3e43)
#define BOOL_CONTROL_CNAME GetString(IDS_RB_BOOLCONTROL)
#define KEY_SELECTED (1<<0)
#define KEY_FLAGGED (1<<1)
#define MAKEBOOL(fl) ( (fl)<=0.0f ? FALSE : TRUE )
class BKey {
public:
TimeValue time;
DWORD flags;
BKey() {flags=0;}
BKey(TimeValue t) {time=t; flags=0;}
};
class BoolControl : public StdControl {
public:
Tab<BKey> keys;
Interval range, valid;
BOOL onOff, startOnOff, rangeLinked;
BoolControl();
// Animatable methods
void DeleteThis() {delete this;}
int IsKeyable() {return 1;}
BOOL IsAnimated() {return keys.Count?TRUE:FALSE;}
Class_ID ClassID() {return BOOL_CONTROL_CLASS_ID;}
SClass_ID SuperClassID() {return CTRL_FLOAT_CLASS_ID;}
void GetClassName(TSTR& s) {s = BOOL_CONTROL_CNAME;}
// Reference methods
RefResult NotifyRefChanged(Interval, RefTargetHandle, PartID&, RefMessage) {return REF_SUCCEED;}
IOResult Save(ISave *isave);
IOResult Load(ILoad *iload);
RefTargetHandle Clone(RemapDir &remap = NoRemap());
// Control methods
void Copy(Control *from);
BOOL IsLeaf() {return TRUE;}
void CommitValue(TimeValue t) {}
void RestoreValue(TimeValue t) {}
void HoldTrack();
Interval GetTimeRange(DWORD flags);
void EditTimeRange(Interval range,DWORD flags);
void MapKeys(TimeMap *map,DWORD flags );
int NumKeys() {return keys.Count();}
TimeValue GetKeyTime(int index) {return keys[index].time;}
int GetKeyIndex(TimeValue t);
void DeleteKeyAtTime(TimeValue t);
BOOL IsKeyAtTime(TimeValue t,DWORD flags);
void DeleteTime(Interval iv, DWORD flags);
void ReverseTime(Interval iv, DWORD flags);
void ScaleTime(Interval iv, float s);
void InsertTime(TimeValue ins, TimeValue amount);
BOOL SupportTimeOperations() {return TRUE;}
void DeleteKeys(DWORD flags);
void DeleteKeyByIndex(int index);
void SelectKeys(TrackHitTab& sel, DWORD flags);
void SelectKeyByIndex(int i,BOOL sel);
void FlagKey(TrackHitRecord hit);
int GetFlagKeyIndex();
int NumSelKeys();
void CloneSelectedKeys(BOOL offset=FALSE);
void AddNewKey(TimeValue t,DWORD flags);
BOOL IsKeySelected(int index);
BOOL CanCopyTrack(Interval iv, DWORD flags) {return TRUE;}
BOOL CanPasteTrack(TrackClipObject *cobj,Interval iv, DWORD flags) {return cobj->ClassID()==ClassID();}
TrackClipObject *CopyTrack(Interval iv, DWORD flags);
void PasteTrack(TrackClipObject *cobj,Interval iv, DWORD flags);
int GetSelKeyCoords(TimeValue &t, float &val,DWORD flags);
void SetSelKeyCoords(TimeValue t, float val,DWORD flags);
int SetSelKeyCoordsExpr(ParamDimension *dim,TCHAR *timeExpr, TCHAR *valExpr, DWORD flags);
int HitTestTrack(
TrackHitTab& hits,
Rect& rcHit,
Rect& rcTrack,
float zoom,
int scroll,
DWORD flags);
int PaintTrack(
ParamDimensionBase *dim,
HDC hdc,
Rect& rcTrack,
Rect& rcPaint,
float zoom,
int scroll,
DWORD flags);
// StdControl methods
void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE) {GetValue(t,val,valid,method);}
void GetValue(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;}
void SortKeys();
};
class BoolClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading) {return new BoolControl();}
const TCHAR * ClassName() {return BOOL_CONTROL_CNAME;}
SClass_ID SuperClassID() {return CTRL_FLOAT_CLASS_ID; }
Class_ID ClassID() {return BOOL_CONTROL_CLASS_ID;}
const TCHAR* Category() {return _T("");}
};
static BoolClassDesc boolCD;
ClassDesc* GetBoolControlDesc() {return &boolCD;}
class BoolControlRestore : public RestoreObj {
public:
Tab<BKey> undo;
Tab<BKey> redo;
Interval urange, rrange;
BoolControl *cont;
BoolControlRestore(BoolControl *c) {
cont = c;
undo = c->keys;
urange = c->range;
}
void Restore(int isUndo) {
if (isUndo) {
redo = cont->keys;
rrange = cont->range;
}
cont->keys = undo;
cont->range = urange;
cont->NotifyDependents(FOREVER,0,REFMSG_CHANGE);
}
void Redo() {
cont->keys = redo;
cont->range = rrange;
cont->NotifyDependents(FOREVER,0,REFMSG_CHANGE);
}
int Size() {return 1;}
void EndHold() {cont->ClearAFlag(A_HELD);}
};
class BoolClipObject : public TrackClipObject {
public:
Tab<BKey> tab;
Class_ID ClassID() {return BOOL_CONTROL_CLASS_ID;}
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
void DeleteThis() {delete this;}
BoolClipObject(Interval iv) : TrackClipObject(iv) {}
};
//-----------------------------------------------------------------------------
BoolControl::BoolControl()
{
//SPEW(("jerryeds","WHY THE FUCK IS BOOL BEING CALLED??? IT SHOULD NEVER BE CALLLED!"));
//MessageBox(NULL, "WHY THE FUCK IS BOOL BEING CALLED??? IT SHOULD NEVER BE CALLLED!", "WTF?", MB_OK);
startOnOff = TRUE;
rangeLinked = TRUE;
}
RefTargetHandle BoolControl::Clone(RemapDir &remap)
{
//SPEW(("jerryeds","WHY THE FUCK IS BOOL BEING CALLED??? IT SHOULD NEVER BE CALLLED!"));
//MessageBox(NULL, "WHY THE FUCK IS BOOL BEING CALLED??? IT SHOULD NEVER BE CALLLED!", "WTF?", MB_OK);
BoolControl *bc = new BoolControl;
bc->range = range;
bc->valid = valid;
bc->keys = keys;
bc->onOff = onOff;
bc->startOnOff = startOnOff;
CloneControl(bc,remap);
return bc;
}
#define KEYTIME_CHUNKID 0x0100
#define KEYFLAGS_CHUNKID 0x0110
#define NUMKEYS_CHUNKID 0x0130
IOResult BoolControl::Save(ISave *isave)
{
//MessageBox(NULL, "WHY THE FUCK IS BOOL BEING CALLED??? IT SHOULD NEVER BE CALLLED!", "WTF?", MB_OK);
//SPEW(("jerryeds","WHY THE FUCK IS BOOL BEING CALLED??? IT SHOULD NEVER BE CALLLED!"));
ULONG nb;
int ct = keys.Count();
// Save the number of keys
isave->BeginChunk(NUMKEYS_CHUNKID);
isave->Write(&ct,sizeof(ct),&nb);
isave->EndChunk();
// Write each key
for (int i=0; i<ct; i++) {
isave->BeginChunk(KEYTIME_CHUNKID);
isave->Write(&keys[i].time,sizeof(keys[i].time),&nb);
isave->EndChunk();
isave->BeginChunk(KEYFLAGS_CHUNKID);
isave->Write(&keys[i].flags,sizeof(keys[i].flags),&nb);
isave->EndChunk();
}
return IO_OK;
}
IOResult BoolControl::Load(ILoad *iload)
{
//MessageBox(NULL, "WHY THE FUCK IS BOOL BEING CALLED??? IT SHOULD NEVER BE CALLLED!", "WTF?", MB_OK);
//SPEW(("jerryeds","WHY THE FUCK IS BOOL BEING CALLED??? IT SHOULD NEVER BE CALLLED!"));
ULONG nb;
int ct;
IOResult res;
if (IO_OK!=(res=iload->OpenChunk())) return res;
assert(iload->CurChunkID()==NUMKEYS_CHUNKID);
iload->Read(&ct,sizeof(ct),&nb);
iload->CloseChunk();
keys.SetCount(ct);
for (int i=0; i<ct; i++) {
iload->OpenChunk();
assert(iload->CurChunkID()==KEYTIME_CHUNKID);
iload->Read(&keys[i].time,sizeof(keys[i].time),&nb);
iload->CloseChunk();
iload->OpenChunk();
assert(iload->CurChunkID()==KEYFLAGS_CHUNKID);
iload->Read(&keys[i].flags,sizeof(keys[i].flags),&nb);
iload->CloseChunk();
}
return IO_OK;
}
void BoolControl::Copy(Control *from)
{
//MessageBox(NULL, "WHY THE FUCK IS BOOL BEING CALLED??? IT SHOULD NEVER BE CALLLED!", "WTF?", MB_OK);
//SPEW(("jerryeds","WHY THE FUCK IS BOOL BEING CALLED??? IT SHOULD NEVER BE CALLLED!"));
if (from) {
if (from->SuperClassID()!=CTRL_FLOAT_CLASS_ID) return;
TimeValue t;
float s;
Interval iv;
TimeValue tpf = GetTicksPerFrame();
Interval v = from->GetTimeRange(TIMERANGE_ALL);
BOOL state = 1;
TimeValue astart = GetAnimStart();
if (v.Start()>astart) {
from->GetValue(astart, &s, iv);
if (s<=0.0f) {
state = 0;
AddNewKey(astart, 0);
}
}
for (t = v.Start(); t<=v.End(); t+=tpf) {
from->GetValue(t, &s, iv);
if (state) {
if (s<=0.0f) {
state = 0;
AddNewKey(t, 0);
}
}
else {
if (s>0.0f) {
state = 1;
AddNewKey(t, 0);
}
}
}
}
}
void BoolControl::HoldTrack()
{
if (theHold.Holding()&&!TestAFlag(A_HELD)) {
theHold.Put(new BoolControlRestore(this));
SetAFlag(A_HELD);
}
}
void BoolControl::EditTimeRange(Interval range,DWORD flags)
{
HoldTrack();
if (flags&EDITRANGE_LINKTOKEYS && keys.Count()) {
this->range.Set(keys[0].time,keys[keys.Count()-1].time);
rangeLinked = TRUE;
} else {
rangeLinked = FALSE;
this->range = range;
}
valid.SetEmpty();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
Interval BoolControl::GetTimeRange(DWORD flags)
{
if (rangeLinked && keys.Count())
return Interval(keys[0].time,keys[keys.Count()-1].time);
else return range;
}
int BoolControl::GetSelKeyCoords(TimeValue &t, float &val,DWORD flags)
{
BOOL tfound=FALSE, tuncommon = FALSE;
int n = keys.Count(), res;
TimeValue atime;
for (int i = 0; i < n; i++ ) {
if (keys[i].flags & KEY_SELECTED) {
if (tfound) {
if (keys[i].time!=atime) {
return KEYS_MULTISELECTED;
}
} else {
tfound = TRUE;
atime = keys[i].time;
}
}
if (tuncommon) return KEYS_MULTISELECTED;
}
t = atime;
res = 0;
if (tfound && !tuncommon) {
res |= KEYS_COMMONTIME;
}
if (!tfound) {
res = KEYS_NONESELECTED;
}
return res;
}
int BoolControl::SetSelKeyCoordsExpr(
ParamDimension *dim,
TCHAR *timeExpr, TCHAR *valExpr, DWORD flags)
{
Expr texpr;
float tfin, tfout=0.0f;
if (timeExpr) {
texpr.defVar(SCALAR_VAR,KEYCOORDS_TIMEVAR);
if (texpr.load(timeExpr)!=EXPR_NORMAL) return KEYCOORDS_EXPR_ERROR;
}
int n = keys.Count();
if (!n) return KEYCOORDS_EXPR_OK;
HoldTrack();
for (int i=0; i<n; i++) {
if (!(flags&KEYCOORDS_VALUEONLY)) {
if (keys[i].flags & KEY_SELECTED) {
tfin = float(keys[i].time)/float(GetTicksPerFrame());
texpr.eval(&tfout, 1, &tfin);
keys[i].time = int(tfout*GetTicksPerFrame());
}
}
}
valid.SetEmpty();
SortKeys();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
return KEYCOORDS_EXPR_OK;
}
void BoolControl::SetSelKeyCoords(TimeValue t, float val,DWORD flags)
{
int n = keys.Count();
if (!n) return;
HoldTrack();
for (int i = 0; i < n; i++ ) {
if (!(flags&KEYCOORDS_VALUEONLY)) {
if (keys[i].flags & KEY_SELECTED) {
keys[i].time = t;
}
}
}
valid.SetEmpty();
SortKeys();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BoolControl::MapKeys(TimeMap *map,DWORD flags)
{
int n = keys.Count();
BOOL changed = FALSE;
if (!n) return;
HoldTrack();
if (flags&TRACK_MAPRANGE) {
TimeValue t0 = map->map(range.Start());
TimeValue t1 = map->map(range.End());
range.Set(t0,t1);
changed = TRUE;
}
if (flags&TRACK_DOALL) {
for (int i=0; i<n; i++) {
keys[i].time = map->map(keys[i].time);
changed = TRUE;
}
} else
if (flags&TRACK_DOSEL) {
BOOL slide = flags&TRACK_SLIDEUNSEL;
TimeValue delta = 0, prev;
int start, end, inc;
if (flags&TRACK_RIGHTTOLEFT) {
start = n-1;
end = -1;
inc = -1;
} else {
start = 0;
end = n;
inc = 1;
}
for (int i=start; i!=end; i+=inc) {
if (keys[i].flags & KEY_SELECTED) {
prev = keys[i].time;
keys[i].time = map->map(keys[i].time);
delta = keys[i].time - prev;
changed = TRUE;
} else if (slide) {
keys[i].time += delta;
}
}
}
if (changed) {
valid.SetEmpty();
SortKeys();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
}
int BoolControl::GetKeyIndex(TimeValue t)
{
for (int i=0; i<keys.Count(); i++) {
if (keys[i].time==t) return i;
if (keys[i].time<t) return -1;
}
return -1;
}
void BoolControl::DeleteKeyAtTime(TimeValue t)
{
int index = GetKeyIndex(t);
if (index>=0) {
HoldTrack();
keys.Delete(index,1);
valid.SetEmpty();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
}
BOOL BoolControl::IsKeyAtTime(TimeValue t,DWORD flags)
{
for (int i=0; i<keys.Count(); i++) {
if (keys[i].time>t) return FALSE;
if (keys[i].time==t) return TRUE;
}
return FALSE;
}
void BoolControl::DeleteTime(Interval iv, DWORD flags)
{
Interval test = TestInterval(iv,flags);
int n = keys.Count();
int d = iv.Duration()-1;
if (d<0) d = 0;
HoldTrack();
for (int i = n-1; i >= 0; i--) {
if (test.InInterval(keys[i].time)) {
keys.Delete(i,1);
} else
if (!(flags&TIME_NOSLIDE)) {
if (keys[i].time > test.End()) {
keys[i].time -= d;
}
}
}
valid.SetEmpty();
SortKeys();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BoolControl::ReverseTime(Interval iv, DWORD flags)
{
Interval test = TestInterval(iv,flags);
int n = keys.Count();
HoldTrack();
for (int i = 0; i < n; i++) {
if (test.InInterval(keys[i].time)) {
TimeValue delta = keys[i].time - iv.Start();
keys[i].time = iv.End()-delta;
}
}
valid.SetEmpty();
SortKeys();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BoolControl::ScaleTime(Interval iv, float s)
{
int n = keys.Count();
TimeValue delta = int(s*float(iv.End()-iv.Start())) + iv.Start()-iv.End();
HoldTrack();
for (int i = 0; i < n; i++) {
if (iv.InInterval(keys[i].time)) {
keys[i].time =
int(s*float(keys[i].time - iv.Start())) + iv.Start();
} else
if (keys[i].time > iv.End()) {
keys[i].time += delta;
}
}
valid.SetEmpty();
SortKeys();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BoolControl::InsertTime(TimeValue ins, TimeValue amount)
{
int n = keys.Count();
HoldTrack();
for (int i = 0; i < n; i++) {
if (keys[i].time >= ins) {
keys[i].time += amount;
}
}
valid.SetEmpty();
SortKeys();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BoolControl::DeleteKeys(DWORD flags)
{
int n = keys.Count();
HoldTrack();
for (int i = n-1; i >= 0; i--) {
if (flags&TRACK_DOALL || keys[i].flags&KEY_SELECTED) {
keys.Delete(i,1);
}
}
valid.SetEmpty();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BoolControl::DeleteKeyByIndex(int index)
{
HoldTrack();
keys.Delete(index,1);
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BoolControl::SelectKeyByIndex(int i,BOOL sel)
{
HoldTrack();
if (sel) keys[i].flags |= KEY_SELECTED;
else keys[i].flags &= ~KEY_SELECTED;
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BoolControl::SelectKeys(TrackHitTab& sel, DWORD flags)
{
HoldTrack();
if (flags&SELKEYS_CLEARKEYS) {
int n = keys.Count();
for (int i = 0; i < n; i++ ) {
keys[i].flags &= ~KEY_SELECTED;
}
}
if (flags&SELKEYS_DESELECT) {
for (int i = 0; i < sel.Count(); i++ ) {
keys[sel[i].hit].flags &= ~KEY_SELECTED;
}
}
if (flags&SELKEYS_SELECT) {
for (int i = 0; i < sel.Count(); i++ ) {
keys[sel[i].hit].flags |= KEY_SELECTED;
}
}
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BoolControl::FlagKey(TrackHitRecord hit)
{
int n = keys.Count();
for (int i = 0; i < n; i++) {
keys[i].flags &= ~KEY_FLAGGED;
}
assert(hit.hit>=0&&hit.hit<(DWORD)n);
keys[hit.hit].flags |= KEY_FLAGGED;
}
int BoolControl::GetFlagKeyIndex()
{
int n = keys.Count();
for (int i = 0; i < n; i++) {
if (keys[i].flags & KEY_FLAGGED) {
return i;
}
}
return -1;
}
int BoolControl::NumSelKeys()
{
int n = keys.Count();
int c = 0;
for ( int i = 0; i < n; i++ ) {
if (keys[i].flags & KEY_SELECTED) {
c++;
}
}
return c;
}
void BoolControl::CloneSelectedKeys(BOOL offset)
{
int n = keys.Count();
HoldTrack();
BOOL changed = FALSE;
for (int i = 0; i < n; i++) {
if (keys[i].flags & KEY_SELECTED) {
BKey key(keys[i].time);
key.flags |= KEY_SELECTED;
keys.Append(1,&key,5);
keys[i].flags &= ~KEY_SELECTED;
changed = TRUE;
}
}
if (changed) {
keys.Shrink();
valid.SetEmpty();
SortKeys();
}
}
void BoolControl::AddNewKey(TimeValue t,DWORD flags)
{
HoldTrack();
BKey key(t);
if (flags&ADDKEY_SELECT) {
key.flags |= KEY_SELECTED;
}
if (flags&ADDKEY_FLAGGED) {
int n = keys.Count();
for (int i = 0; i < n; i++) {
keys[i].flags &= ~KEY_FLAGGED;
}
key.flags |= KEY_FLAGGED;
}
keys.Append(1,&key);
valid.SetEmpty();
SortKeys();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
BOOL BoolControl::IsKeySelected(int index)
{
return keys[index].flags & KEY_SELECTED;
}
TrackClipObject *BoolControl::CopyTrack(Interval iv, DWORD flags)
{
BoolClipObject *cobj = new BoolClipObject(iv);
Interval test = TestInterval(iv,flags);
for (int i = 0; i < keys.Count(); i++) {
if (test.InInterval(keys[i].time)) {
BKey nk(keys[i].time);
cobj->tab.Append(1,&nk,10);
}
}
cobj->tab.Shrink();
return cobj;
}
void BoolControl::PasteTrack(TrackClipObject *cobj,Interval iv, DWORD flags)
{
BoolClipObject *cob = (BoolClipObject*)cobj;
HoldTrack();
DeleteTime(iv,flags);
InsertTime(iv.Start(),cob->clip.Duration()-1);
for (int i = 0; i < cob->tab.Count(); i++) {
BKey key(cob->tab[i].time);
key.time -= cob->clip.Start() - iv.Start();
keys.Append(1,&key);
}
valid.SetEmpty();
SortKeys();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
int BoolControl::HitTestTrack(
TrackHitTab& hits,
Rect& rcHit,
Rect& rcTrack,
float zoom,
int scroll,
DWORD flags)
{
int left = ScreenToTime(rcTrack.left,zoom,scroll) - 4;
int right = ScreenToTime(rcTrack.right,zoom,scroll) + 4;
int n = keys.Count();
int y = (rcTrack.top+rcTrack.bottom)/2;
for ( int i = 0; i < n; i++ ) {
if (flags&HITTRACK_SELONLY &&
!(keys[i].flags & KEY_SELECTED)) continue;
if (flags&HITTRACK_UNSELONLY &&
(keys[i].flags & KEY_SELECTED)) continue;
if (keys[i].time > right) {
break;
}
if (keys[i].time > left) {
int x = TimeToScreen(keys[i].time,zoom,scroll);
if (rcHit.Contains(IPoint2(x,y))) {
TrackHitRecord rec(i,0);
hits.Append(1,&rec);
if (flags&HITTRACK_ABORTONHIT) return TRACK_DONE;
}
}
}
return TRACK_DONE;
}
int BoolControl::PaintTrack(
ParamDimensionBase *dim,
HDC hdc,
Rect& rcTrack,
Rect& rcPaint,
float zoom,
int scroll,
DWORD flags)
{
int left = ScreenToTime(rcPaint.left-8,zoom,scroll);
int right = ScreenToTime(rcPaint.right+8,zoom,scroll);
int n = keys.Count();
int y = (rcTrack.top+rcTrack.bottom)/2, lx, x = rcPaint.left-2;
HBRUSH selBrush = CreateSolidBrush(RGB(255,255,255));
HBRUSH barBrush = CreateSolidBrush(RGB(113,160,231)); //RGB(80,100,180)
HBRUSH unselBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
BOOL state = startOnOff;
SelectObject(hdc,GetStockObject(BLACK_PEN));
SelectObject(hdc,barBrush);
for (int i = 0; i < n; i++) {
lx = x;
x = TimeToScreen(keys[i].time,zoom,scroll);
if (keys[i].time > left) {
if (state) {
Rectangle(hdc,lx,y-4,x,y+4);
}
}
state = !state;
if (keys[i].time > right) {
break;
}
}
if (state) {
Rectangle(hdc,x,y-4,rcPaint.right,y+4);
}
for (i = 0; i < n; i++) {
if (keys[i].time > right) {
break;
}
if (keys[i].time > left) {
x = TimeToScreen(keys[i].time,zoom,scroll);
if ((flags&PAINTTRACK_SHOWSEL) && (keys[i].flags&KEY_SELECTED)) {
SelectObject(hdc,selBrush);
} else {
SelectObject(hdc,unselBrush);
}
Ellipse(hdc,x-4,y-5,x+4,y+5);
}
}
DeleteObject(selBrush);
DeleteObject(barBrush);
return TRACK_DONE;
}
void BoolControl::GetValue(
TimeValue t, void *val, Interval &valid, GetSetMethod method)
{
Interval wvalid = FOREVER;
float *v = (float*)val;
t = ApplyEase(t,wvalid);
if (!this->valid.InInterval(t)) {
onOff = startOnOff;
for (int i=0; i<keys.Count(); i++) {
if (keys[i].time>t) break;
onOff = !onOff;
}
if (keys.Count()) {
if (t < keys[0].time) {
this->valid.Set(TIME_NegInfinity,keys[0].time-1);
} else
if (t > keys[keys.Count()-1].time) {
this->valid.Set(keys[keys.Count()-1].time,TIME_PosInfinity);
} else this->valid.SetInstant(t);
} else {
this->valid = FOREVER;
}
}
valid &= this->valid;
*v = onOff ? 1.0f : -1.0f;
}
void BoolControl::SetValueLocalTime(
TimeValue t, void *val, int commit, GetSetMethod method)
{
float *v = (float*)val;
float tv;
GetValue(t,&tv,FOREVER);
if (MAKEBOOL(tv) == MAKEBOOL(*v)) {
return;
}
if (Animating()) {
int index = GetKeyIndex(t);
if (index>=0) {
keys.Delete(index,1);
keys.Shrink();
} else {
BKey k(t);
keys.Append(1,&k);
SortKeys();
}
} else {
if (keys.Count()) {
startOnOff = !startOnOff;
} else {
onOff = startOnOff = MAKEBOOL(*v);
}
}
valid.SetEmpty();
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
void BoolControl::Extrapolate(
Interval range,TimeValue t,void *val,Interval &valid,int type)
{
GetValue(t,val,valid);
}
static int __cdecl CompareBKeys(const BKey *k1, const BKey *k2)
{
if (k1->time < k2->time) return -1;
if (k1->time > k2->time) return 1;
return 0;
}
void BoolControl::SortKeys()
{
keys.Sort((CompareFnc)CompareBKeys);
}
#endif
@@ -0,0 +1,925 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_FUNC_LIST DIALOG DISCARDABLE 0, 0, 234, 214
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Function List"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "Close",IDOK,177,193,50,14
LISTBOX IDC_FUNC_LIST,6,5,220,183,LBS_SORT | LBS_USETABSTOPS |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
END
IDD_EXPRPARAMS DIALOG DISCARDABLE 0, 0, 374, 202
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU
CAPTION "Expression Controller"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_VAR_NAME,39,15,53,13,ES_AUTOHSCROLL
CONTROL "Scalar",IDC_SCALAR_RB,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,14,32,35,10
CONTROL "Vector",IDC_VECTOR_RB,"Button",BS_AUTORADIOBUTTON,55,32,
35,10
PUSHBUTTON "Create",IDC_CREATE_VAR,102,12,53,14
PUSHBUTTON "Delete",IDC_DELETE_VAR,102,28,53,14
LISTBOX IDC_SCALAR_LIST,5,89,76,73,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
LISTBOX IDC_VECTOR_LIST,88,89,75,73,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Assign to Constant",IDC_ASGN_CONST,5,183,75,14
PUSHBUTTON "Assign to Controller",IDC_ASGN_CNTRL,87,183,75,14
EDITTEXT IDC_EXPR_EDIT,180,17,182,66,ES_MULTILINE |
ES_AUTOVSCROLL | ES_AUTOHSCROLL
EDITTEXT IDC_DESCRIPTION,180,102,183,47,ES_MULTILINE |
ES_AUTOVSCROLL | ES_AUTOHSCROLL
PUSHBUTTON "Save",IDC_SAVE,178,183,26,14
PUSHBUTTON "Load",IDC_LOAD,205,183,26,14
PUSHBUTTON "Evaluate",IDC_EXPR_EVAL,290,183,39,14
DEFPUSHBUTTON "Close",IDOK,330,183,39,14
GROUPBOX "Create Variables",IDC_STATIC,5,4,158,42
RTEXT "Name:",IDC_STATIC,11,18,22,8
LTEXT "Scalars",IDC_STATIC,6,80,30,8
LTEXT "Vectors",IDC_STATIC,89,80,30,8
LTEXT "Assigned to:",IDC_STATIC,7,166,43,8
LTEXT "",IDC_CUR_ASGN,49,166,117,8
GROUPBOX "Expression",IDC_STATIC,176,4,192,84
GROUPBOX "Description",IDC_STATIC,176,92,192,60
PUSHBUTTON "Function List",IDC_FUNCTIONS,299,159,68,14
LTEXT "T = ticks",IDC_STATIC,179,158,30,8
LTEXT "S = secs",IDC_STATIC,179,167,30,8
LTEXT "F = frames",IDC_STATIC,222,158,35,8
LTEXT "NT = normalized time",IDC_STATIC,222,167,70,8
RTEXT "Tick Offset:",IDC_STATIC,46,61,38,8
LTEXT "",IDC_EXPLAIN_NOTATION,180,78,182,8,NOT WS_VISIBLE
PUSHBUTTON "Debug",IDC_EXPR_DEBUG,244,183,33,14
GROUPBOX "Variable Parameters",IDC_STATIC,5,48,158,29
CONTROL "",IDC_OFFSET,"CustEdit",WS_TABSTOP,88,60,31,10
CONTROL "",IDC_OFFSET_SPIN,"SpinnerControl",0x0,120,60,7,10
END
IDD_SCALAR_ASGN DIALOG DISCARDABLE 0, 0, 110, 79
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Assign Constant"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,6,59,45,14
PUSHBUTTON "Cancel",IDCANCEL,56,59,45,14
GROUPBOX "Scalar Value",IDC_STATIC,9,7,89,42
CONTROL "",IDC_EXPR_CONST,"CustEdit",WS_TABSTOP,28,25,40,10
CONTROL "",IDC_EXPR_CONST_SPIN,"SpinnerControl",0x0,69,25,7,10
END
IDD_VECTOR_ASGN DIALOG DISCARDABLE 0, 0, 193, 77
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Assign Constant"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,86,58,46,14
PUSHBUTTON "Cancel",IDCANCEL,137,58,46,14
GROUPBOX "Vector Value",IDC_STATIC,7,8,177,40
LTEXT ",",IDC_STATIC,63,30,4,8
LTEXT ",",IDC_STATIC,121,30,4,8
CONTROL "",IDC_VEC_Z,"CustEdit",WS_TABSTOP,129,27,40,10
CONTROL "",IDC_VEC_Z_SPIN,"SpinnerControl",0x0,171,27,7,10
CONTROL "",IDC_VEC_Y,"CustEdit",WS_TABSTOP,72,27,40,10
CONTROL "",IDC_VEC_Y_SPIN,"SpinnerControl",0x0,113,27,7,10
CONTROL "",IDC_VEC_X,"CustEdit",WS_TABSTOP,14,27,40,10
CONTROL "",IDC_VEC_X_SPIN,"SpinnerControl",0x0,55,27,7,10
END
IDD_EULER_PARAMS DIALOG DISCARDABLE 0, 0, 108, 37
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "X",IDC_EULER_X,"CustButton",WS_TABSTOP,59,21,12,12
CONTROL "Y",IDC_EULER_Y,"CustButton",WS_TABSTOP,73,21,12,12
CONTROL "Z",IDC_EULER_Z,"CustButton",WS_TABSTOP,87,21,12,12
RTEXT "Rotation Axis:",IDC_STATIC,6,24,51,8
COMBOBOX IDC_EULER_ORDER,59,4,41,105,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
RTEXT "Axis Order:",IDC_STATIC,9,7,48,8
END
IDD_PATHJOINTPARAMS DIALOG DISCARDABLE 0, 0, 108, 79
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Active",IDC_XACTIVE,"Button",BS_AUTOCHECKBOX,13,11,34,
10
CONTROL "Limited",IDC_XLIMITED,"Button",BS_AUTOCHECKBOX,13,24,35,
10
CONTROL "Ease",IDC_XEASE,"Button",BS_AUTOCHECKBOX,59,24,30,10
CONTROL "",IDC_XFROM,"CustEdit",WS_TABSTOP,13,46,30,10
CONTROL "",IDC_XTO,"CustEdit",WS_TABSTOP,59,46,30,10
CONTROL "",IDC_XDAMPING,"CustEdit",WS_TABSTOP,59,60,30,10
GROUPBOX "Percent Along Path",IDC_STATIC,4,0,101,76
CONTROL "",IDC_XFROMSPIN,"SpinnerControl",0x0,45,46,7,10
CONTROL "",IDC_XTOSPIN,"SpinnerControl",0x0,91,46,7,10
LTEXT "From:",IDC_JP_XFROMLABEL,13,36,21,8
LTEXT "To:",IDC_JP_XTOLABEL,59,36,13,8
CONTROL "",IDC_XDAMPINGSPIN,"SpinnerControl",0x0,91,60,7,10
RTEXT "Damping:",IDC_JP_XDAMPINGLABEL,28,60,30,8
END
IDD_PATHPARAMS DIALOG DISCARDABLE 0, 0, 108, 181
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Pick Path",IDC_PICKPATH,"CustButton",0x0,16,30,74,12
CONTROL "",IDC_PATHPERCENT,"CustEdit",WS_TABSTOP,56,62,35,10
CONTROL "Follow",IDC_PATH_FOLLOW,"Button",BS_AUTOCHECKBOX,12,76,
35,10
CONTROL "Bank",IDC_PATH_BANK,"Button",BS_AUTOCHECKBOX,54,76,35,
10
CONTROL "",IDC_FOLLOW_BANK,"CustEdit",WS_TABSTOP,56,91,35,10
CONTROL "",IDC_FOLLOW_TRACK,"CustEdit",WS_TABSTOP,56,105,35,10
CONTROL "Allow Upside Down",IDC_PATH_ALLOWFLIP,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,12,119,77,10
CONTROL "Constant Velocity",IDC_PATH_CONSTVEL,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,12,133,77,10
CONTROL "X",IDC_PATH_X,"Button",BS_AUTORADIOBUTTON | WS_GROUP,10,
161,19,10
CONTROL "Y",IDC_PATH_Y,"Button",BS_AUTORADIOBUTTON,32,161,19,10
CONTROL "Z",IDC_PATH_Z,"Button",BS_AUTORADIOBUTTON,52,161,19,10
CONTROL "Flip",IDC_PATH_FLIP,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,75,161,24,10
LTEXT "CurrentPathObjectName",IDC_PATHNAME,9,16,88,8
GROUPBOX "Current Path Object:",IDC_STATIC,5,3,98,47
CONTROL "",IDC_FOLLOW_BANKSPIN,"SpinnerControl",0x0,92,91,7,10
RTEXT "Bank Amount:",IDC_FOLLOW_BANKLABEL,8,91,47,8
GROUPBOX "Path Options:",IDC_STATIC,5,51,98,98
CONTROL "",IDC_FOLLOW_TRACKSPIN,"SpinnerControl",0x0,92,105,7,10
RTEXT "Smoothness:",IDC_FOLLOW_TRACKLABEL,8,105,47,8
CONTROL "",IDC_PATHPERCENTSPIN,"SpinnerControl",0x0,92,62,7,10
RTEXT "% Along Path:",IDC_FOLLOW_BANKLABEL2,8,62,47,8
GROUPBOX "Axis:",IDC_STATIC,5,150,98,26
END
IDD_NOISEPARAMS DIALOG DISCARDABLE 0, 0, 213, 146
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Noise Parameters"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "",IDC_NOISE_SEED,"CustEdit",WS_TABSTOP,53,8,30,10
CONTROL "",IDC_NOISE_FREQ,"CustEdit",WS_TABSTOP,53,24,30,10
CONTROL "",IDC_NOISE_ROUGH,"CustEdit",WS_TABSTOP,53,64,30,10
CONTROL "",IDC_NOISE_XSTRENGTH,"CustEdit",WS_TABSTOP,140,8,39,10
CONTROL "",IDC_NOISE_YSTRENGTH,"CustEdit",WS_TABSTOP,140,21,39,
10
CONTROL "",IDC_NOISE_ZSTRENGTH,"CustEdit",WS_TABSTOP,140,34,39,
10
CONTROL "",IDC_NOISE_RAMPIN,"CustEdit",WS_TABSTOP,140,51,39,10
CONTROL "",IDC_NOISE_RAMPOUT,"CustEdit",WS_TABSTOP,140,64,39,10
CONTROL "Fractal Noise",IDC_NOISE_FRACTAL,"Button",
BS_AUTOCHECKBOX | BS_LEFTTEXT,34,51,57,10
CONTROL ">0",IDC_NOISE_XLIM0,"Button",BS_AUTOCHECKBOX,189,9,22,
10
CONTROL ">0",IDC_NOISE_YLIM0,"Button",BS_AUTOCHECKBOX,189,22,22,
10
CONTROL ">0",IDC_NOISE_ZLIM0,"Button",BS_AUTOCHECKBOX,189,35,22,
10
CONTROL "",IDC_NOISE_XSTRENGTHSPIN,"SpinnerControl",0x0,180,8,7,
10
RTEXT "X Strength:",IDC_NOISE_XSTRENGTHLABEL,95,8,44,8
CONTROL "",IDC_NOISE_FREQSPIN,"SpinnerControl",0x0,84,24,7,10
RTEXT "Frequency:",IDC_STATIC,10,24,41,8
CONTROL "",IDC_NOISE_SEEDSPIN,"SpinnerControl",0x0,84,8,7,10
RTEXT "Seed:",IDC_STATIC,16,8,35,8
CONTROL "",IDC_NOISE_YSTRENGTHSPIN,"SpinnerControl",0x0,180,21,7,
10
RTEXT "Y Strength:",IDC_NOISE_YSTRENGTHLABEL,95,21,44,8
CONTROL "",IDC_NOISE_ZSTRENGTHSPIN,"SpinnerControl",0x0,180,34,7,
10
RTEXT "Z Strength:",IDC_NOISE_ZSTRENGTHLABEL,95,34,44,8
CONTROL "",IDC_NOISE_ROUGHSPIN,"SpinnerControl",0x0,84,64,7,10
RTEXT "Roughness:",IDC_NOISE_ROUGHLABEL,10,64,41,8
CONTROL "",IDC_NOISE_GRAPH,"NoiseGraph",0x0,8,90,179,46
CONTROL "",IDC_NOISE_RAMPINSPIN,"SpinnerControl",0x0,180,51,7,10
RTEXT "Ramp in:",IDC_NOISE_ZSTRENGTHLABEL2,103,52,36,8
CONTROL "",IDC_NOISE_RAMPOUTSPIN,"SpinnerControl",0x0,180,64,7,
10
RTEXT "Ramp out:",IDC_NOISE_ZSTRENGTHLABEL3,103,65,36,8
LTEXT "Characteristic Graph:",IDC_STATIC,8,80,73,8
END
IDD_IPOS_PARAMS DIALOG DISCARDABLE 0, 0, 108, 21
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "X",IDC_IPOS_X,"CustButton",WS_TABSTOP,59,4,12,12
CONTROL "Y",IDC_IPOS_Y,"CustButton",WS_TABSTOP,73,4,12,12
CONTROL "Z",IDC_IPOS_Z,"CustButton",WS_TABSTOP,87,4,12,12
RTEXT "Position Axis:",IDC_STATIC,6,7,51,8
END
IDD_ATTACH_PARAMS DIALOG DISCARDABLE 0, 0, 108, 381
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Pick Object",IDC_ATTACH_PICKOB,"CustButton",WS_TABSTOP,
15,24,76,12
GROUPBOX "Attach To:",IDC_STATIC,4,2,100,50
CTEXT "Object01",IDC_ATTACH_OBNAME,6,12,94,8
GROUPBOX "Key Info:",IDC_STATIC,4,93,100,284
CONTROL "Set Position",IDC_ATTACH_SETPOS,"CustButton",WS_TABSTOP,
15,221,76,12
CONTROL "",IDC_ATTACH_KEYTIME,"CustEdit",WS_TABSTOP,51,116,27,10
CONTROL "",IDC_ATTACH_KEYTIMESPIN,"SpinnerControl",0x0,79,116,7,
10
RTEXT "Time:",IDC_STATIC,23,116,26,8
CONTROL "",IDC_ATTACH_KEYFACE,"CustEdit",WS_TABSTOP,51,138,27,10
CONTROL "",IDC_ATTACH_KEYFACESPIN,"SpinnerControl",0x0,79,138,7,
10
RTEXT "Face:",IDC_STATIC,23,139,26,8
CONTROL "<",IDC_PREVKEY,"CustButton",0x0,8,103,11,11
CONTROL ">",IDC_NEXTKEY,"CustButton",0x0,20,103,11,11
CONTROL "",IDC_KEYNUM,"CustStatus",0x0,33,104,22,9
GROUPBOX "Position:",IDC_STATIC,8,129,92,110
CONTROL "",IDC_ATTACH_KEYA,"CustEdit",WS_TABSTOP,51,151,27,10
CONTROL "",IDC_ATTACH_KEYASPIN,"SpinnerControl",0x0,79,151,7,10
RTEXT "A:",IDC_STATIC,23,153,26,8
CONTROL "",IDC_ATTACH_KEYB,"CustEdit",WS_TABSTOP,51,164,27,10
CONTROL "",IDC_ATTACH_KEYBSPIN,"SpinnerControl",0x0,79,164,7,10
RTEXT "B:",IDC_STATIC,23,165,26,8
CONTROL "",IDC_ATTACH_FACEPOSGRAPH,"FacePosGraph",WS_TABSTOP,20,
177,66,41
GROUPBOX "TCB:",IDC_STATIC,8,239,92,134
CONTROL "",IDC_TCB_GRAPH,"TCBGraph",0x0,20,313,66,54
CONTROL "",IDC_ATTACH_KEYTENS,"CustEdit",WS_TABSTOP,51,248,27,10
CONTROL "",IDC_ATTACH_KEYTENSSPIN,"SpinnerControl",0x0,79,248,7,
10
RTEXT "Tension:",IDC_STATIC,20,249,29,8
CONTROL "",IDC_ATTACH_KEYCONT,"CustEdit",WS_TABSTOP,51,261,27,10
CONTROL "",IDC_ATTACH_KEYCONTSPIN,"SpinnerControl",0x0,79,261,7,
10
RTEXT "Continuity:",IDC_STATIC,15,262,34,8
CONTROL "",IDC_ATTACH_KEYBIAS,"CustEdit",WS_TABSTOP,51,274,27,10
CONTROL "",IDC_ATTACH_KEYBIASSPIN,"SpinnerControl",0x0,79,274,7,
10
RTEXT "Bias:",IDC_STATIC,20,275,29,8
CONTROL "",IDC_ATTACH_KEYEASETO,"CustEdit",WS_TABSTOP,51,287,27,
10
CONTROL "",IDC_ATTACH_KEYEASETOSPIN,"SpinnerControl",0x0,79,287,
7,10
RTEXT "Ease To:",IDC_STATIC,20,288,29,8
CONTROL "",IDC_ATTACH_KEYEASEFROM,"CustEdit",WS_TABSTOP,51,300,
27,10
CONTROL "",IDC_ATTACH_KEYEASEFROMSPIN,"SpinnerControl",0x0,79,
300,7,10
RTEXT "Ease From:",IDC_STATIC,11,301,38,8
CONTROL "Align To Surface",IDC_ATTACH_ALIGN,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,15,39,69,10
GROUPBOX "Update:",IDC_STATIC,4,52,100,40
CONTROL "Manual Update",IDC_ATTACH_MANUPDATE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,15,79,65,10
CONTROL "Update",IDC_ATTACH_UPDATE,"CustButton",WS_TABSTOP,15,64,
76,12
END
IDD_ATTACH_DIALOG DIALOGEX 0, 0, 195, 137
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_TOOLWINDOW
CAPTION "Attachment"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
CONTROL "",IDC_ATTACH_KEYTIME,"CustEdit",WS_TABSTOP,47,22,27,10
CONTROL "",IDC_ATTACH_KEYTIMESPIN,"SpinnerControl",0x0,75,22,7,
10
RTEXT "Time:",IDC_STATIC,19,22,26,8
CONTROL "",IDC_ATTACH_KEYFACE,"CustEdit",WS_TABSTOP,47,49,27,10
CONTROL "",IDC_ATTACH_KEYFACESPIN,"SpinnerControl",0x0,75,49,7,
10
RTEXT "Face:",IDC_STATIC,19,50,26,8
CONTROL "<",IDC_PREVKEY,"CustButton",0x0,3,3,11,11
CONTROL ">",IDC_NEXTKEY,"CustButton",0x0,15,3,11,11
CONTROL "",IDC_KEYNUM,"CustStatus",0x0,29,4,22,9
GROUPBOX "Position:",IDC_STATIC,3,35,92,100
CONTROL "",IDC_ATTACH_KEYA,"CustEdit",WS_TABSTOP,47,62,27,10
CONTROL "",IDC_ATTACH_KEYASPIN,"SpinnerControl",0x0,75,62,7,10
RTEXT "A:",IDC_STATIC,19,64,26,8
CONTROL "",IDC_ATTACH_KEYB,"CustEdit",WS_TABSTOP,47,75,27,10
CONTROL "",IDC_ATTACH_KEYBSPIN,"SpinnerControl",0x0,75,75,7,10
RTEXT "B:",IDC_STATIC,19,76,26,8
CONTROL "",IDC_ATTACH_FACEPOSGRAPH,"FacePosGraph",WS_TABSTOP,17,
88,66,41
GROUPBOX "TCB:",IDC_STATIC,100,1,92,134
CONTROL "",IDC_TCB_GRAPH,"TCBGraph",0x0,113,75,66,54
CONTROL "",IDC_ATTACH_KEYTENS,"CustEdit",WS_TABSTOP,144,10,27,10
CONTROL "",IDC_ATTACH_KEYTENSSPIN,"SpinnerControl",0x0,172,10,7,
10
RTEXT "Tension:",IDC_STATIC,112,11,29,8
CONTROL "",IDC_ATTACH_KEYCONT,"CustEdit",WS_TABSTOP,144,23,27,10
CONTROL "",IDC_ATTACH_KEYCONTSPIN,"SpinnerControl",0x0,172,23,7,
10
RTEXT "Continuity:",IDC_STATIC,108,24,34,8
CONTROL "",IDC_ATTACH_KEYBIAS,"CustEdit",WS_TABSTOP,144,36,27,10
CONTROL "",IDC_ATTACH_KEYBIASSPIN,"SpinnerControl",0x0,172,36,7,
10
RTEXT "Bias:",IDC_STATIC,112,37,29,8
CONTROL "",IDC_ATTACH_KEYEASETO,"CustEdit",WS_TABSTOP,144,49,27,
10
CONTROL "",IDC_ATTACH_KEYEASETOSPIN,"SpinnerControl",0x0,172,49,
7,10
RTEXT "Ease To:",IDC_STATIC,112,50,29,8
CONTROL "",IDC_ATTACH_KEYEASEFROM,"CustEdit",WS_TABSTOP,144,62,
27,10
CONTROL "",IDC_ATTACH_KEYEASEFROMSPIN,"SpinnerControl",0x0,172,
62,7,10
RTEXT "Ease From:",IDC_STATIC,104,62,38,8
END
IDD_EXPR_DEBUG DIALOGEX 0, 0, 221, 174
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU
CAPTION "Expression Debug Window"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
PUSHBUTTON "Close",IDCANCEL,172,153,42,14
LISTBOX IDC_DEBUG_LIST,7,16,207,106,LBS_SORT | LBS_USETABSTOPS |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP,
WS_EX_DLGMODALFRAME
LTEXT "Variables:",IDC_STATIC,7,7,32,8
LTEXT "Expression value:",IDC_STATIC,7,131,56,8
CTEXT "",IDC_DEBUG_VALUE,69,130,145,11,SS_SUNKEN
PUSHBUTTON "Evaluate",IDC_EXPR_EVAL,125,153,42,14,NOT WS_VISIBLE
END
IDD_LINK_PARAMS DIALOG DISCARDABLE 0, 0, 108, 118
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Add Link",IDC_LINK_PICK,"CustButton",WS_TABSTOP,10,6,87,
12
LISTBOX IDC_LINK_LIST,10,38,87,60,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_LINK_TIME,"CustEdit",WS_TABSTOP,52,102,30,10
CONTROL "",IDC_LINK_TIMESPIN,"SpinnerControl",0x0,83,102,7,10
RTEXT "Start Time:",IDC_LINK_TIMELABEL,13,102,37,8
CONTROL "Delete Link",IDC_LINK_DELETE,"CustButton",WS_TABSTOP,10,
22,87,12
END
IDD_FOLLOW_PANEL DIALOG DISCARDABLE 0, 0, 108, 203
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Apply Follow",IDC_FOLLOW_APPLY,5,28,98,14
PUSHBUTTON "Close",IDOK,29,184,46,13
LTEXT "Sphere01",IDC_SEL_NAME,10,10,89,8
GROUPBOX "Selected Object:",IDC_STATIC,4,0,100,23
CONTROL "Bank",IDC_PATH_BANK,"Button",BS_AUTOCHECKBOX,12,58,35,
10
CONTROL "",IDC_FOLLOW_BANK,"CustEdit",WS_TABSTOP,56,73,35,10
CONTROL "",IDC_FOLLOW_TRACK,"CustEdit",WS_TABSTOP,56,87,35,10
CONTROL "",IDC_FOLLOW_BANKSPIN,"SpinnerControl",0x0,92,73,7,10
RTEXT "Bank Amount:",IDC_FOLLOW_BANKLABEL,8,73,47,8
CONTROL "",IDC_FOLLOW_TRACKSPIN,"SpinnerControl",0x0,92,87,7,10
RTEXT "Smoothness:",IDC_FOLLOW_TRACKLABEL,8,87,47,8
CONTROL "Allow Upside Down",IDC_PATH_ALLOWFLIP,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,12,102,77,10
GROUPBOX "Follow Options:",IDC_STATIC,4,46,100,72
CONTROL "",IDC_FOLLOW_START,"CustEdit",WS_TABSTOP,44,133,35,10
CONTROL "",IDC_FOLLOW_STARTSPIN,"SpinnerControl",0x0,80,133,7,10
RTEXT "Start:",IDC_STATIC,19,133,24,8
GROUPBOX "Samples:",IDC_STATIC,4,120,100,55
CONTROL "",IDC_FOLLOW_END,"CustEdit",WS_TABSTOP,44,146,35,10
CONTROL "",IDC_FOLLOW_ENDSPIN,"SpinnerControl",0x0,80,146,7,10
RTEXT "End:",IDC_STATIC,19,146,24,8
CONTROL "",IDC_FOLLOW_SAMP,"CustEdit",WS_TABSTOP,44,159,35,10
CONTROL "",IDC_FOLLOW_SAMPSPIN,"SpinnerControl",0x0,80,159,7,10
RTEXT "Samples:",IDC_STATIC,12,159,31,8
END
IDD_SURFPARAMS DIALOG DISCARDABLE 0, 0, 108, 150
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Pick Surface",IDC_PICKSURF,"CustButton",0x0,16,30,74,12
CONTROL "",IDC_SURF_U,"CustEdit",WS_TABSTOP,50,63,35,10
CONTROL "",IDC_SURF_V,"CustEdit",WS_TABSTOP,50,76,35,10
CONTROL "No Alignment",IDC_ALIGN_NONE,"Button",
BS_AUTORADIOBUTTON | WS_GROUP,26,92,58,10
CONTROL "Align to U",IDC_ALIGN_U,"Button",BS_AUTORADIOBUTTON,26,
104,47,10
CONTROL "Align to V",IDC_ALIGN_V,"Button",BS_AUTORADIOBUTTON,26,
115,46,10
LTEXT "CurrentSurfObjectName",IDC_SURFNAME,9,16,88,8
GROUPBOX "Current Surface Object:",IDC_STATIC,5,3,98,47
GROUPBOX "Surface Options:",IDC_STATIC,5,51,98,94
CONTROL "",IDC_SURF_USPIN,"SpinnerControl",0x0,86,63,7,10
RTEXT "U Position:",IDC_STATIC,12,63,37,8
CONTROL "",IDC_SURF_VSPIN,"SpinnerControl",0x0,86,76,7,10
RTEXT "V Position:",IDC_STATIC,12,76,37,8
CONTROL "Flip",IDC_ALIGN_FLIP,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,27,128,27,10
END
IDD_SURFJOINTPARAMS DIALOG DISCARDABLE 0, 0, 108, 158
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Active",IDC_XACTIVE,"Button",BS_AUTOCHECKBOX,13,11,34,
10
CONTROL "Limited",IDC_XLIMITED,"Button",BS_AUTOCHECKBOX,13,24,35,
10
CONTROL "Ease",IDC_XEASE,"Button",BS_AUTOCHECKBOX,59,24,30,10
CONTROL "",IDC_XFROM,"CustEdit",WS_TABSTOP,13,46,30,10
CONTROL "",IDC_XTO,"CustEdit",WS_TABSTOP,59,46,30,10
CONTROL "",IDC_XDAMPING,"CustEdit",WS_TABSTOP,59,60,30,10
GROUPBOX "U:",IDC_STATIC,4,0,101,76
CONTROL "",IDC_XFROMSPIN,"SpinnerControl",0x0,45,46,7,10
CONTROL "",IDC_XTOSPIN,"SpinnerControl",0x0,91,46,7,10
LTEXT "From:",IDC_JP_XFROMLABEL,13,36,21,8
LTEXT "To:",IDC_JP_XTOLABEL,59,36,13,8
CONTROL "",IDC_XDAMPINGSPIN,"SpinnerControl",0x0,91,60,7,10
RTEXT "Damping:",IDC_JP_XDAMPINGLABEL,28,60,30,8
CONTROL "Active",IDC_YACTIVE,"Button",BS_AUTOCHECKBOX,13,89,34,
10
CONTROL "Limited",IDC_YLIMITED,"Button",BS_AUTOCHECKBOX,13,102,
35,10
CONTROL "Ease",IDC_YEASE,"Button",BS_AUTOCHECKBOX,59,102,30,10
CONTROL "",IDC_YFROM,"CustEdit",WS_TABSTOP,13,124,30,10
CONTROL "",IDC_YTO,"CustEdit",WS_TABSTOP,59,124,30,10
CONTROL "",IDC_YDAMPING,"CustEdit",WS_TABSTOP,59,138,30,10
GROUPBOX "V:",IDC_STATIC,4,78,101,76
CONTROL "",IDC_YFROMSPIN,"SpinnerControl",0x0,45,124,7,10
CONTROL "",IDC_YTOSPIN,"SpinnerControl",0x0,91,124,7,10
LTEXT "From:",IDC_JP_YFROMLABEL,13,114,21,8
LTEXT "To:",IDC_JP_YTOLABEL,59,114,13,8
CONTROL "",IDC_YDAMPINGSPIN,"SpinnerControl",0x0,91,138,7,10
RTEXT "Damping:",IDC_JP_YDAMPINGLABEL,23,138,35,8
END
IDD_STDJOINTPARAMS DIALOG DISCARDABLE 0, 0, 108, 302
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Active",IDC_XACTIVE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,13,11,34,10
CONTROL "Limited",IDC_XLIMITED,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,13,24,35,10
CONTROL "Ease",IDC_XEASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
61,24,30,10
CONTROL "",IDC_XFROM,"CustEdit",WS_TABSTOP,13,46,30,10
CONTROL "",IDC_XTO,"CustEdit",WS_TABSTOP,61,46,30,10
CONTROL "Spring Back",IDC_XSPINGBACK,"Button",BS_AUTOCHECKBOX |
BS_LEFTTEXT | BS_RIGHT | WS_TABSTOP,5,59,53,10
CONTROL "",IDC_XSPRING,"CustEdit",WS_TABSTOP,61,59,30,10
CONTROL "",IDC_XSPRINGTENS,"CustEdit",WS_TABSTOP,61,72,30,10
CONTROL "",IDC_XDAMPING,"CustEdit",WS_TABSTOP,61,85,30,10
CONTROL "Active",IDC_YACTIVE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,14,110,34,10
CONTROL "Limited",IDC_YLIMITED,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,14,123,35,10
CONTROL "Ease",IDC_YEASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
61,123,30,10
CONTROL "",IDC_YFROM,"CustEdit",WS_TABSTOP,14,145,30,10
CONTROL "",IDC_YTO,"CustEdit",WS_TABSTOP,61,145,30,10
CONTROL "Spring Back",IDC_YSPINGBACK,"Button",BS_AUTOCHECKBOX |
BS_LEFTTEXT | BS_RIGHT | WS_TABSTOP,5,158,53,10
CONTROL "",IDC_YSPRING,"CustEdit",WS_TABSTOP,61,158,30,10
CONTROL "",IDC_YSPRINGTENS,"CustEdit",WS_TABSTOP,61,171,30,10
CONTROL "",IDC_YDAMPING,"CustEdit",WS_TABSTOP,61,184,30,10
CONTROL "Active",IDC_ZACTIVE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,14,209,34,10
CONTROL "Limited",IDC_ZLIMITED,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,14,222,35,10
CONTROL "Ease",IDC_ZEASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
61,222,30,10
CONTROL "",IDC_ZFROM,"CustEdit",WS_TABSTOP,14,244,30,10
CONTROL "",IDC_ZTO,"CustEdit",WS_TABSTOP,61,244,30,10
CONTROL "Spring Back",IDC_ZSPINGBACK,"Button",BS_AUTOCHECKBOX |
BS_LEFTTEXT | BS_RIGHT | WS_TABSTOP,5,257,53,10
CONTROL "",IDC_ZSPRING,"CustEdit",WS_TABSTOP,61,257,30,10
CONTROL "",IDC_ZSPRINGTENS,"CustEdit",WS_TABSTOP,61,270,30,10
CONTROL "",IDC_ZDAMPING,"CustEdit",WS_TABSTOP,61,283,30,10
GROUPBOX "X Axis",1611,4,0,101,99
CONTROL "",IDC_XFROMSPIN,"SpinnerControl",0x0,45,46,7,10
CONTROL "",IDC_XTOSPIN,"SpinnerControl",0x0,93,46,7,10
LTEXT "From:",IDC_JP_XFROMLABEL,13,36,21,8
LTEXT "To:",IDC_JP_XTOLABEL,61,36,13,8
CONTROL "",IDC_XDAMPINGSPIN,"SpinnerControl",0x0,93,85,7,10
RTEXT "Damping:",IDC_JP_XDAMPINGLABEL,30,85,30,8
GROUPBOX "Y Axis",1612,4,99,101,99
CONTROL "",IDC_YFROMSPIN,"SpinnerControl",0x0,46,145,7,10
CONTROL "",IDC_YTOSPIN,"SpinnerControl",0x0,93,145,7,10
LTEXT "From:",IDC_JP_YFROMLABEL,14,135,21,8
LTEXT "To:",IDC_JP_YTOLABEL,59,135,13,8
CONTROL "",IDC_YDAMPINGSPIN,"SpinnerControl",0x0,93,184,7,10
RTEXT "Damping:",IDC_JP_YDAMPINGLABEL,30,184,30,8
GROUPBOX "Z Axis",1613,4,198,101,99
CONTROL "",IDC_ZFROMSPIN,"SpinnerControl",0x0,46,244,7,10
CONTROL "",IDC_ZTOSPIN,"SpinnerControl",0x0,93,244,7,10
LTEXT "From:",IDC_JP_ZFROMLABEL,14,234,21,8
LTEXT "To:",IDC_JP_ZTOLABEL,61,234,13,8
CONTROL "",IDC_ZDAMPINGSPIN,"SpinnerControl",0x0,93,283,7,10
RTEXT "Damping:",IDC_JP_ZDAMPINGLABEL,30,283,30,8
CONTROL "",IDC_XSPRINGSPIN,"SpinnerControl",0x0,93,59,7,10
CONTROL "",IDC_YSPRINGSPIN,"SpinnerControl",0x0,93,158,7,10
CONTROL "",IDC_ZSPRINGSPIN,"SpinnerControl",0x0,93,257,7,10
CONTROL "",IDC_XSPRINGTENSSPIN,"SpinnerControl",0x0,93,72,7,10
RTEXT "Spring Tension:",IDC_STATIC,9,73,50,8
CONTROL "",IDC_YSPRINGTENSSPIN,"SpinnerControl",0x0,93,171,7,10
RTEXT "Spring Tension:",IDC_STATIC,9,172,50,8
CONTROL "",IDC_ZSPRINGTENSSPIN,"SpinnerControl",0x0,93,270,7,10
RTEXT "Spring Tension:",IDC_STATIC,9,271,50,8
END
IDD_LOD_UTILPARAMS DIALOG DISCARDABLE 0, 0, 108, 333
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
LISTBOX IDC_LOD_LIST,4,135,100,60,LBS_USETABSTOPS |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
CONTROL "Display In Viewports",IDC_LOD_VIEWPORTOBJ,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,14,198,79,10
CONTROL "",IDC_LOD_VIEWWIDTH,"CustEdit",WS_TABSTOP,51,83,30,10
CONTROL "",IDC_LOD_VIEWHEIGHT,"CustEdit",WS_TABSTOP,51,96,30,10
CONTROL "Pixels",IDC_LOD_DISPPIXELS,"Button",BS_AUTORADIOBUTTON |
WS_GROUP,21,223,34,10
CONTROL "% of Target Image",IDC_LOD_DISPPERCENT,"Button",
BS_AUTORADIOBUTTON,21,234,73,10
CONTROL "",IDC_LOD_MIN,"CustEdit",WS_TABSTOP,51,263,30,10
CONTROL "",IDC_LOD_MAX,"CustEdit",WS_TABSTOP,51,276,30,10
PUSHBUTTON "Reset All",IDC_LOD_RESET,26,291,64,13
CONTROL "Add To Set",IDC_LOD_ADDTOSET,"CustButton",WS_TABSTOP,20,
33,68,13
CONTROL "Remove From Set",IDC_LOD_DELETEFROMSET,"CustButton",
WS_TABSTOP,20,50,68,13
CONTROL "Create New Set",IDC_LOD_CREATENEWSET,"CustButton",
WS_TABSTOP,20,16,68,13
PUSHBUTTON "Close",IDOK,28,315,50,13
CONTROL "",IDC_LOD_MINSPIN,"SpinnerControl",0x0,82,263,7,10
RTEXT "Min Size:",IDC_LOD_MINLABEL,15,263,34,8
CONTROL "",IDC_LOD_MAXSPIN,"SpinnerControl",0x0,82,276,7,10
RTEXT "Max Size:",IDC_LOD_MAXLABEL,15,276,34,8
GROUPBOX "Thresholds:",IDC_STATIC,4,250,100,60
GROUPBOX "Level of Detail Set:",IDC_STATIC,4,2,100,68
CONTROL "",IDC_LOD_VIEWWIDTHSPIN,"SpinnerControl",0x0,82,83,7,10
RTEXT "Width:",IDC_STATIC,22,83,27,8
CONTROL "",IDC_LOD_VIEWHEIGHTSPIN,"SpinnerControl",0x0,82,96,7,
10
RTEXT "Height:",IDC_STATIC,22,96,27,8
GROUPBOX "Image Output Size:",IDC_STATIC,4,71,100,59
GROUPBOX "Threshold Units:",IDC_STATIC,4,211,100,38
PUSHBUTTON "Reset to Current",IDC_LOD_RESETOUTPUT,26,111,64,13
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_EXPRPARAMS, DIALOG
BEGIN
BOTTOMMARGIN, 197
END
IDD_EULER_PARAMS, DIALOG
BEGIN
BOTTOMMARGIN, 21
END
IDD_ATTACH_PARAMS, DIALOG
BEGIN
LEFTMARGIN, 4
RIGHTMARGIN, 104
VERTGUIDE, 8
VERTGUIDE, 100
END
IDD_EXPR_DEBUG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 214
TOPMARGIN, 7
BOTTOMMARGIN, 167
END
IDD_STDJOINTPARAMS, DIALOG
BEGIN
BOTTOMMARGIN, 266
END
IDD_LOD_UTILPARAMS, DIALOG
BEGIN
BOTTOMMARGIN, 328
END
END
#endif // APSTUDIO_INVOKED
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,5,0,0
PRODUCTVERSION 2,5,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Kinetix, a division of Autodesk, Inc.\0"
VALUE "FileVersion", "2.5.0.0\0"
VALUE "InternalName", "ctrl\0"
VALUE "LegalCopyright", "Copyright © 1998 Autodesk Inc.\0"
VALUE "OriginalFilename", "ctrl.dlc\0"
VALUE "ProductName", "3D Studio MAX\0"
VALUE "ProductVersion", "2.5.0.0\0"
VALUE "FileDescription", "Standard controllers (plugin)\0"
VALUE "LegalTrademarks", "The following are registered trademarks of Autodesk, Inc.: 3D Studio MAX. The following are trademarks of Autodesk, Inc.: Kinetix, Kinetix(logo), BIPED, Physique, Character Studio, MAX DWG, DWG Unplugged, Heidi, FLI, FLC, DXF.\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DB_BAD_NAME "Invalid variable name"
IDS_DB_POSITION_EXPR "Position Expression"
IDS_DB_POINT3_EXPR "Point3 Expression"
IDS_DB_FLOAT_EXPR "Float Expression"
IDS_DB_SCALE_EXPR "Scale Expression"
IDS_DB_ROTATION_EXPR "Rotation Expression"
IDS_DB_CIRCULAR_DEPENDENCY "Circular Dependency"
IDS_DB_CANT_ASSIGN "Can't Assign Controller"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_DB_EXPR_PARSE_ERROR "Error Parsing Expression"
IDS_DB_DUPNAME "Duplicate Name"
IDS_DB_CANT_CREATE_VAR "Can't Create Variable"
IDS_DB_NOSUCH "No Such Variable: %s"
IDS_DB_CANT_CHANGE_OFFSET "Can't Change Offset"
IDS_DB_NOCURVAR "No Current Variable"
IDS_DB_CANTDELETE "Can't Delete %s"
IDS_DB_EXPRCNTL "Expression Controller"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_DB_NOTHINGDEL "Nothing to Delete"
IDS_DB_XPR_FILES "Expression Files (*.xpr)"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_DB_NEED_VECTOR "Need a vector expression"
IDS_DB_NEED_SCALAR "Need a scalar expression"
IDS_DB_SAVE_EXPR "Save Expression As"
IDS_DB_LOAD_EXPR "Load Expression"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_RB_EXPRESSIONCONTROLTITLE "Expression Controller : "
IDS_RB_PICKPATH "Pick Path"
IDS_DB_FN_SIN "sin(x)\ttrigonometric sine of x"
IDS_DB_FN_NOISE "noise(x,y,z)\t3D noise function"
IDS_DB_FN_IF "if(c,t,f)\tconditional: value is t if c is true, else value is f"
IDS_DB_FN_MIN "min(x,y)\tminimum of x and y"
IDS_DB_FN_MAX "max(x,y)\tmaximum of x and y"
IDS_DB_FN_POW "pow(x,y)\tx raised to the power y"
IDS_DB_FN_MOD "mod(x,y)\tremainder of x divided by y"
IDS_DB_FN_DEGTORAD "degToRad(x)\tx converted from degrees to radians"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_RB_PATH "Path"
IDS_RB_EULERXYZ "Euler XYZ"
IDS_RB_EULERPARAMS "Euler Parameters"
IDS_RB_XROTATION "X Rotation"
IDS_RB_YROTATION "Y Rotation"
IDS_RB_ZROTATION "Z Rotation"
IDS_RB_NOISEFLOAT "Noise Float"
IDS_RB_NOISEPOSITION "Noise Position"
IDS_RB_NOISEPOINT3 "Noise Point3"
IDS_RB_NOISEROTATION "Noise Rotation"
IDS_RB_NOISESCALE "Noise Scale"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_RB_ROTJOINTPARAMS "Rotational Joints"
IDS_RB_PATHJOINTPARAMS "Path Joint"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_RB_PERCENT "Percent"
IDS_RB_PATHPARAMS "Path Parameters"
IDS_RB_NONE "None"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_RB_PATHCONTROLLER "Path Controller"
IDS_RB_ILLEGALPATH "Using this path would create a circular dependency."
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_RB_NOISECONTROLTITLE "Noise Controller : "
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_RB_STRENGTH "Strength:"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_DB_FN_RADTODEG "radToDeg(x)\tx converted from radians to degrees"
IDS_DB_FN_COS "cos(x)\ttrigonometric cosine of x"
IDS_DB_FN_TAN "tan(x)\ttrigonometric tangent of x"
IDS_DB_FN_ASIN "asin(x)\tarcsine of x"
IDS_DB_FN_ACOS "acos(x)\tarccosine of x"
IDS_DB_FN_ATAN "atan(x)\tarctangent of x"
IDS_DB_FN_SINH "sinh(x)\thyperbolic sine of x"
IDS_DB_FN_COSH "cosh(x)\thyperbolic cosine of x"
IDS_DB_FN_TANH "tanh(x)\thyperbolic tangent of x"
IDS_DB_FN_LN "ln(x)\tnatural logarithm (base e) of x"
IDS_DB_FN_LOG "log(x)\tcommon logarithm (base 10) of x"
IDS_DB_FN_EXP "exp(x)\te raised to the power x"
IDS_DB_FN_SQRT "sqrt(x)\tsquare root of x"
IDS_DB_FN_ABS "abs(x)\tabsolute value of x"
IDS_DB_FN_CEIL "ceil(x)\tsmallest integer greater than or equal to x"
IDS_DB_FN_FLOOR "floor(x)\tlargest integer less than or equal to x"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_DB_FN_COMP "comp(v,i)\ti'th component of v"
IDS_DB_FN_UNIT "unit(v)\tunit vector in the direction of v"
IDS_DB_FN_LENGTH "length(v)\tlength of v"
IDS_DB_FN_PI "pi\tthe constant pi (3.1415...)"
IDS_DB_FN_E "e\tthe constant e (2.71828...)"
IDS_DB_FN_TPS "TPS\tnumber of ticks per second"
IDS_DB_FN_VIF "vif(c,v1,v2)\t""vector if"" - value is v1 if c is true, else v2"
IDS_RB_NOISESTRENGTH "Noise Strength"
IDS_RB_SETPERCENT "Set Path %"
IDS_RB_BOOLCONTROL "On/Off"
IDS_RB_IPOSPARAMS "Position XYZ Parameters"
IDS_RB_IPOS "Position XYZ"
IDS_RB_XPOSITION "X Position"
IDS_RB_YPOSITION "Y Position"
IDS_RB_ZPOSITION "Z Position"
IDS_RB_ATTACHCONTROL "Attachment"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_RB_ATTACHPARAMS "Attachment Parameters"
IDS_RB_EDITATTACHKEY "Edit Attachment Key"
IDS_RB_ATTACHCONTROLLER "Attachment Controller"
IDS_RB_ILLEGALOBJECT "Illegal Object"
IDS_RB_ATTACHTITLE "Attachment Controller:"
IDS_RB_IPOINT3 "Point3 XYZ"
IDS_RB_IPOINT3PARAMS "Point3 XYZ Parameters"
IDS_RB_ICOLOR "Color RGB"
IDS_RB_ICOLORPARAMS "Color RGB Parameters"
IDS_RB_LINKCTRL "Link Control"
IDS_RB_TRANSFORM "Transform"
IDS_RB_LINKPARAMS "Link Parameters"
IDS_RB_SETLINKTIME "Set Link Time"
IDS_RB_DELETELINK "Delete Link"
IDS_RB_ADDLINK "Pick Link"
IDS_RB_FOLLOWUTIL "Follow/Bank"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_RB_MULTISEL "Multiple Selected"
IDS_RB_NONESEL "None Selected"
IDS_RB_APPLYFOLLOW "Apply Follow"
IDS_RB_SURF "Surface"
IDS_RB_U "U"
IDS_RB_V "V"
IDS_RB_CHANGEUV "Change UV"
IDS_RB_SURFPARAMS "Surface Controller Parameters"
IDS_RB_SURFJOINTPARAMS "Surface Joint"
IDS_RB_EULERTYPE0 "XYZ"
IDS_RB_EULERTYPE1 "XZY"
IDS_RB_EULERTYPE2 "YZX"
IDS_RB_EULERTYPE3 "YXZ"
IDS_RB_EULERTYPE4 "ZXY"
IDS_RB_EULERTYPE5 "ZYX"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_RB_EULERTYPE6 "XYX"
IDS_RB_EULERTYPE7 "YZY"
IDS_RB_EULERTYPE8 "ZXZ"
IDS_RB_X "X"
IDS_RB_Y "Y"
IDS_RB_Z "Z"
IDS_RB_XAXIS "X Axis"
IDS_RB_YAXIS "Y Axis"
IDS_RB_ZAXIS "Z Axis"
IDS_RB_EULERNAME "Euler %s"
IDS_RB_LODCONTROL "LOD Controller"
IDS_RB_LODUTILITU "Level of Detail"
IDS_RB_LODSAMEPARENT "All Level of Detail objects must be grouped."
IDS_RB_DEFCONTROLLERS "Standard controllers (Kinetix)"
IDS_RB_CHANGESTRENGTH "Change Strength"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
@@ -0,0 +1,149 @@
/**********************************************************************
*<
FILE: ctrl.cpp
DESCRIPTION: DLL implementation of some controllers
CREATED BY: Rolf Berteig
HISTORY: created 13 June 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "ctrl.h"
#include "buildver.h"
HINSTANCE hInstance;
int controlsInit = FALSE;
/** public functions **/
BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) {
hInstance = hinstDLL;
if ( !controlsInit ) {
controlsInit = TRUE;
// jaguar controls
InitCustomControls(hInstance);
#ifdef OLD3DCONTROLS
// initialize 3D controls
Ctl3dRegister(hinstDLL);
Ctl3dAutoSubclass(hinstDLL);
#endif
// initialize Chicago controls
InitCommonControls();
SetDefaultBoolController(GetBoolControlDesc());
}
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return(TRUE);
}
//------------------------------------------------------
// This is the interface to Jaguar:
//------------------------------------------------------
__declspec( dllexport ) const TCHAR *
LibDescription() { return
GetString(IDS_RB_DEFCONTROLLERS); }
#ifndef DESIGN_VER
/// MUST CHANGE THIS NUMBER WHEN ADD NEW CLASS
__declspec( dllexport ) int LibNumberClasses() {return 21;}
__declspec( dllexport ) ClassDesc*
LibClassDesc(int i) {
switch(i) {
case 0: return GetPathCtrlDesc();
case 1: return GetEulerCtrlDesc();
case 2: return GetFloatNoiseDesc();
case 3: return GetExprPosCtrlDesc();
case 4: return GetExprP3CtrlDesc();
case 5: return GetExprFloatCtrlDesc();
case 6: return GetExprScaleCtrlDesc();
case 7: return GetPositionNoiseDesc();
case 8: return GetPoint3NoiseDesc();
case 9: return GetRotationNoiseDesc();
case 10: return GetScaleNoiseDesc();
case 11: return GetBoolControlDesc();
case 12: return GetIPosCtrlDesc();
case 13: return GetAttachControlDesc();
case 14: return GetIPoint3CtrlDesc();
case 15: return GetIColorCtrlDesc();
case 16: return GetLinkCtrlDesc();
case 17: return GetFollowUtilDesc();
case 18: return GetSurfCtrlDesc();
case 19: return GetLODControlDesc();
case 20: return GetLODUtilDesc();
// case 7: return GetExprRotCtrlDesc();
default: return 0;
}
}
#else
/// MUST CHANGE THIS NUMBER WHEN ADD NEW CLASS
__declspec( dllexport ) int LibNumberClasses() { return 17; }
__declspec( dllexport ) ClassDesc*
LibClassDesc(int i) {
switch(i) {
case 0: return GetPathCtrlDesc();
case 1: return GetEulerCtrlDesc();
case 2: return GetFloatNoiseDesc();
// case 3: return GetExprPosCtrlDesc();
// case 4: return GetExprP3CtrlDesc();
// case 5: return GetExprFloatCtrlDesc();
// case 6: return GetExprScaleCtrlDesc();
case 3: return GetPositionNoiseDesc();
case 4: return GetPoint3NoiseDesc();
case 5: return GetRotationNoiseDesc();
case 6: return GetScaleNoiseDesc();
case 7: return GetBoolControlDesc();
case 8: return GetIPosCtrlDesc();
case 9: return GetAttachControlDesc();
case 10: return GetIPoint3CtrlDesc();
case 11: return GetIColorCtrlDesc();
case 12: return GetLinkCtrlDesc();
case 13: return GetFollowUtilDesc();
case 14: return GetSurfCtrlDesc();
case 15: return GetLODControlDesc();
case 16: return GetLODUtilDesc();
default: return 0;
}
}
#endif
// Return version so can detect obsolete DLLs
__declspec( dllexport ) ULONG
LibVersion() { return VERSION_3DSMAX; }
TCHAR *GetString(int id)
{
static TCHAR buf[256];
if(hInstance)
return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL;
return NULL;
}
@@ -0,0 +1,53 @@
/**********************************************************************
*<
FILE: ctrl.h
DESCRIPTION:
CREATED BY: Rolf Berteig
HISTORY:
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#ifndef __CTRL__H
#define __CTRL__H
#include "Max.h"
#include "resource.h"
extern ClassDesc* GetPathCtrlDesc();
extern ClassDesc* GetEulerCtrlDesc();
extern ClassDesc* GetExprPosCtrlDesc();
extern ClassDesc* GetExprP3CtrlDesc();
extern ClassDesc* GetExprFloatCtrlDesc();
extern ClassDesc* GetExprScaleCtrlDesc();
extern ClassDesc* GetExprRotCtrlDesc();
extern ClassDesc* GetFloatNoiseDesc();
extern ClassDesc* GetPositionNoiseDesc();
extern ClassDesc* GetPoint3NoiseDesc();
extern ClassDesc* GetRotationNoiseDesc();
extern ClassDesc* GetScaleNoiseDesc();
extern ClassDesc* GetBoolControlDesc();
extern ClassDesc* GetIPosCtrlDesc();
extern ClassDesc* GetAttachControlDesc();
extern ClassDesc* GetIPoint3CtrlDesc();
extern ClassDesc* GetIColorCtrlDesc();
extern ClassDesc* GetLinkCtrlDesc();
extern ClassDesc* GetFollowUtilDesc();
extern ClassDesc* GetSurfCtrlDesc();
extern ClassDesc* GetLODControlDesc();
extern ClassDesc* GetLODUtilDesc();
TCHAR *GetString(int id);
extern HINSTANCE hInstance;
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,306 @@
#ifndef __EXPCTRL__H
#define __EXPCTRL__H
#include "ctrl.h"
#include "units.h"
#include "exprlib.h"
#define EXPR_POS_CONTROL_CNAME GetString(IDS_DB_POSITION_EXPR)
#define EXPR_P3_CONTROL_CNAME GetString(IDS_DB_POINT3_EXPR)
#define EXPR_FLOAT_CONTROL_CNAME GetString(IDS_DB_FLOAT_EXPR)
#define EXPR_SCALE_CONTROL_CNAME GetString(IDS_DB_SCALE_EXPR)
#define EXPR_ROT_CONTROL_CNAME GetString(IDS_DB_ROTATION_EXPR)
#define EXPR_TICKS 0
#define EXPR_SECS 1
#define EXPR_FRAMES 2
#define EXPR_NTIME 3
class ExprControl;
// for the debug floater window
class ExprDebug : public TimeChangeCallback {
public:
HWND hWnd;
ExprControl *ec;
TimeValue t;
static int winX, winY;
ExprDebug(HWND hParent, ExprControl *exprControl);
~ExprDebug();
void Invalidate();
void SetTime(TimeValue tm) { t = tm; }
void Update();
void Init(HWND hWnd);
void TimeChanged(TimeValue t) { SetTime(t); Update(); }
};
// scalar variables
class SVar {
public:
TSTR name;
int regNum; // register number variable is assigned to
int refID; // < 0 means constant
float val; // value, if constant
int subNum;
int offset; // tick offset
};
class VVar {
public:
TSTR name;
int regNum; // reg num this var is assigned to
int refID; // < 0 means constant
Point3 val; // value, if const
int subNum;
int offset; // tick offset
};
MakeTab(SVar);
MakeTab(VVar);
class VarRef {
public:
VarRef() { client = NULL; refCt = 0; }
VarRef(ReferenceTarget *c) { client = c; refCt = 1; }
ReferenceTarget *client;
int refCt;
};
MakeTab(VarRef);
class ExprControl : public StdControl
{
public:
int type;
Expr expr;
int timeSlots[4];
int sRegCt;
int vRegCt;
int curIndex;
Point3 curPosVal;
float curFloatVal;
Interval ivalid;
Interval range;
HWND hParams;
IObjParam * ip;
SVarTab sVars;
VVarTab vVars;
VarRefTab refTab;
TSTR desc;
HFONT hFixedFont;
HWND hDlg;
ExprDebug *edbg;
static int winX, winY;
void updRegCt(int val, int type);
BOOL dfnVar(int type, TCHAR *buf, int slot, int offset);
int getVarCount(int type) { return type == SCALAR_VAR ? sVars.Count() : vVars.Count(); }
TCHAR * getVarName(int type, int i);
int getVarOffset(int type, int i);
int getRegNum(int type, int i);
float getScalarValue(int i);
Point3 getVectorValue(int i);
BOOL assignScalarValue(int i, float val);
BOOL assignVectorValue(int i, Point3 &val);
BOOL assignController(int type, int i, ReferenceTarget *client, int subNum);
void deleteAllVars();
ExprControl(int type, ExprControl &ctrl);
ExprControl(int type, BOOL loading);
~ExprControl();
// Animatable methods
int TrackParamsType() { return TRACKPARAMS_WHOLE; }
void DeleteThis() { delete this; }
int IsKeyable() { return 0; }
BOOL IsAnimated() {return TRUE;}
Interval GetTimeRange(DWORD flags) { return range; }
void EditTimeRange(Interval range,DWORD flags);
void Hold();
void MapKeys( TimeMap *map, DWORD flags );
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev );
void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next );
void EditTrackParams(
TimeValue t, // The horizontal position of where the user right clicked.
ParamDimensionBase *dim,
TCHAR *pname,
HWND hParent,
IObjParam *ip,
DWORD flags);
// Reference methods
int NumRefs() { return StdControl::NumRefs() + refTab.Count(); }
ReferenceTarget* GetReference(int i);
void SetReference(int i, RefTargetHandle rtarg);
RefResult NotifyRefChanged(Interval, RefTargetHandle, PartID&, RefMessage);
void RefDeleted();
IOResult Save(ISave *isave);
IOResult Load(ILoad *iload);
// Control methods
void Copy(Control *from);
RefTargetHandle Clone(RemapDir& remap=NoRemap()) {
ExprControl *ctrl = new ExprControl(this->type, *this);
CloneControl(ctrl,remap);
return ctrl;
}
BOOL IsLeaf() { return TRUE; }
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();
void DeleteTempValue(void *val);
void ApplyValue(void *val, void *delta);
void MultiplyValue(void *val, float m);
void GetAbsoluteControlValue(INode *node,TimeValue t,Point3 *pt,Interval &iv);
};
class ExprPosControl : public ExprControl
{
public:
ExprPosControl(ExprPosControl &ctrl) : ExprControl(EXPR_POS_CONTROL_CLASS_ID, ctrl) {}
ExprPosControl(BOOL loading=FALSE) : ExprControl(EXPR_POS_CONTROL_CLASS_ID, loading) {}
~ExprPosControl() {}
RefTargetHandle Clone(RemapDir& remap=NoRemap()) { return(new ExprPosControl(*this)); }
void GetClassName(TSTR& s) { s = EXPR_POS_CONTROL_CNAME; }
Class_ID ClassID() { return Class_ID(EXPR_POS_CONTROL_CLASS_ID,0); }
SClass_ID SuperClassID() { return CTRL_POSITION_CLASS_ID; }
};
class ExprP3Control : public ExprControl
{
public:
ExprP3Control(ExprP3Control &ctrl) : ExprControl(EXPR_P3_CONTROL_CLASS_ID, ctrl) {}
ExprP3Control(BOOL loading=FALSE) : ExprControl(EXPR_P3_CONTROL_CLASS_ID, loading) {}
~ExprP3Control() {}
RefTargetHandle Clone(RemapDir& remap=NoRemap()) { return(new ExprP3Control(*this)); }
void GetClassName(TSTR& s) { s = EXPR_P3_CONTROL_CNAME; }
Class_ID ClassID() { return Class_ID(EXPR_P3_CONTROL_CLASS_ID,0); }
SClass_ID SuperClassID() { return CTRL_POINT3_CLASS_ID; }
};
class ExprFloatControl : public ExprControl
{
public:
ExprFloatControl(ExprFloatControl &ctrl) : ExprControl(EXPR_FLOAT_CONTROL_CLASS_ID, ctrl) {}
ExprFloatControl(BOOL loading=FALSE) : ExprControl(EXPR_FLOAT_CONTROL_CLASS_ID, loading) {}
~ExprFloatControl() {}
RefTargetHandle Clone(RemapDir& remap=NoRemap()) { return(new ExprFloatControl(*this)); }
void GetClassName(TSTR& s) { s = EXPR_FLOAT_CONTROL_CNAME; }
Class_ID ClassID() { return Class_ID(EXPR_FLOAT_CONTROL_CLASS_ID,0); }
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
};
class ExprScaleControl : public ExprControl
{
public:
ExprScaleControl(ExprScaleControl &ctrl) : ExprControl(EXPR_SCALE_CONTROL_CLASS_ID, ctrl) {}
ExprScaleControl(BOOL loading=FALSE) : ExprControl(EXPR_SCALE_CONTROL_CLASS_ID, loading) {}
~ExprScaleControl() {}
RefTargetHandle Clone(RemapDir& remap=NoRemap()) { return(new ExprScaleControl(*this)); }
void GetClassName(TSTR& s) { s = EXPR_SCALE_CONTROL_CNAME; }
Class_ID ClassID() { return Class_ID(EXPR_SCALE_CONTROL_CLASS_ID,0); }
SClass_ID SuperClassID() { return CTRL_SCALE_CLASS_ID; }
};
class ExprRotControl : public ExprControl
{
public:
ExprRotControl(ExprRotControl &ctrl) : ExprControl(EXPR_ROT_CONTROL_CLASS_ID, ctrl) {}
ExprRotControl(BOOL loading=FALSE) : ExprControl(EXPR_ROT_CONTROL_CLASS_ID, loading) {}
~ExprRotControl() {}
RefTargetHandle Clone(RemapDir& remap=NoRemap()) { return(new ExprRotControl(*this)); }
void GetClassName(TSTR& s) { s = EXPR_ROT_CONTROL_CNAME; }
Class_ID ClassID() { return Class_ID(EXPR_ROT_CONTROL_CLASS_ID,0); }
SClass_ID SuperClassID() { return CTRL_ROTATION_CLASS_ID; }
};
//********************************************************
// EXPRESSION CONTROL
//********************************************************
static Class_ID exprPosControlClassID(EXPR_POS_CONTROL_CLASS_ID,0);
class ExprPosClassDesc:public ClassDesc
{
public:
int IsPublic() { return 1; }
void * Create(BOOL loading) { return new ExprPosControl(loading); }
const TCHAR * ClassName() { return EXPR_POS_CONTROL_CNAME; }
SClass_ID SuperClassID() { return CTRL_POSITION_CLASS_ID; }
Class_ID ClassID() { return exprPosControlClassID; }
const TCHAR* Category() { return _T(""); }
};
static ExprPosClassDesc exprPosCD;
ClassDesc* GetExprPosCtrlDesc();
static Class_ID exprP3ControlClassID(EXPR_P3_CONTROL_CLASS_ID,0);
class ExprP3ClassDesc:public ClassDesc
{
public:
int IsPublic() { return 1; }
void * Create(BOOL loading) { return new ExprP3Control(loading); }
const TCHAR * ClassName() { return EXPR_P3_CONTROL_CNAME; }
SClass_ID SuperClassID() { return CTRL_POINT3_CLASS_ID; }
Class_ID ClassID() { return exprP3ControlClassID; }
const TCHAR* Category() { return _T(""); }
};
static ExprP3ClassDesc exprP3CD;
ClassDesc* GetExprP3CtrlDesc();
static Class_ID exprFloatControlClassID(EXPR_FLOAT_CONTROL_CLASS_ID,0);
class ExprFloatClassDesc:public ClassDesc
{
public:
int IsPublic() { return 1; }
void * Create(BOOL loading) { return new ExprFloatControl(loading); }
const TCHAR * ClassName() { return EXPR_FLOAT_CONTROL_CNAME; }
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; }
Class_ID ClassID() { return exprFloatControlClassID; }
const TCHAR* Category() { return _T(""); }
};
static ExprFloatClassDesc exprFloatCD;
ClassDesc* GetExprFloatCtrlDesc();
static Class_ID exprScaleControlClassID(EXPR_SCALE_CONTROL_CLASS_ID,0);
class ExprScaleClassDesc:public ClassDesc
{
public:
int IsPublic() { return 1; }
void * Create(BOOL loading) { return new ExprScaleControl(loading); }
const TCHAR * ClassName() { return EXPR_SCALE_CONTROL_CNAME; }
SClass_ID SuperClassID() { return CTRL_SCALE_CLASS_ID; }
Class_ID ClassID() { return exprScaleControlClassID; }
const TCHAR* Category() { return _T(""); }
};
static ExprScaleClassDesc exprScaleCD;
ClassDesc* GetExprScaleCtrlDesc();
static Class_ID exprRotControlClassID(EXPR_ROT_CONTROL_CLASS_ID,0);
class ExprRotClassDesc:public ClassDesc
{
public:
int IsPublic() { return 1; }
void * Create(BOOL loading) { return new ExprRotControl(loading); }
const TCHAR * ClassName() { return EXPR_ROT_CONTROL_CNAME; }
SClass_ID SuperClassID() { return CTRL_ROTATION_CLASS_ID; }
Class_ID ClassID() { return exprRotControlClassID; }
const TCHAR* Category() { return _T(""); }
};
static ExprFloatClassDesc exprRotCD;
ClassDesc* GetExprRotCtrlDesc();
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,389 @@
/**********************************************************************
*<
FILE: followu.cpp
DESCRIPTION: A utility that generates path follow
CREATED BY: Rolf Berteig
HISTORY: created 1/27/97
*> Copyright (c) 1996, All Rights Reserved.
**********************************************************************/
#include "ctrl.h"
#include "utilapi.h"
#define FOLLOW_CLASS_ID Class_ID(0x4557a2c4,0x00186d34)
#define FOLLOW_CNAME GetString(IDS_RB_FOLLOWUTIL)
class FollowUtil : public UtilityObj {
public:
IUtil *iu;
Interface *ip;
HWND hPanel;
BOOL bank, flip;
float bankAmount, tracking;
TimeValue start, end;
int samples;
FollowUtil();
void BeginEditParams(Interface *ip,IUtil *iu);
void EndEditParams(Interface *ip,IUtil *iu);
void DeleteThis() {}
void SelectionSetChanged(Interface *ip,IUtil *iu);
void Init(HWND hWnd);
void Destroy(HWND hWnd);
void SetStates(HWND hWnd);
Matrix3 CalcRefFrame(TimeValue t,INode *node);
Point3 GetPosition(INode *node,TimeValue t);
void DoFollow();
};
static FollowUtil theFollowUtil;
//--- Class Descriptor ------------------------------------------
class FollowUtilClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE) {return &theFollowUtil;}
const TCHAR * ClassName() {return FOLLOW_CNAME;}
SClass_ID SuperClassID() {return UTILITY_CLASS_ID;}
Class_ID ClassID() {return FOLLOW_CLASS_ID;}
const TCHAR* Category() {return _T("");}
void ResetClassParams(BOOL fileReset);
};
void FollowUtilClassDesc::ResetClassParams(BOOL fileReset)
{
if (fileReset) {
theFollowUtil = FollowUtil();
}
}
static FollowUtilClassDesc followUtilDesc;
ClassDesc* GetFollowUtilDesc() {return &followUtilDesc;}
#define BANKSCALE 100.0f
#define FromBankUI(a) ((a)*BANKSCALE)
#define ToBankUI(a) ((a)/BANKSCALE)
#define TRACKSCALE 0.04f
#define FromTrackUI(a) ((a)*TRACKSCALE)
#define ToTrackUI(a) ((a)/TRACKSCALE)
///--- Panel Proc ------------------------------------------------
static BOOL CALLBACK FollowUtilDlgProc(
HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
theFollowUtil.Init(hWnd);
break;
case WM_DESTROY:
theFollowUtil.Destroy(hWnd);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_PATH_BANK:
theFollowUtil.bank = IsDlgButtonChecked(hWnd,IDC_PATH_BANK);
theFollowUtil.SetStates(hWnd);
break;
case IDC_PATH_ALLOWFLIP:
theFollowUtil.flip = IsDlgButtonChecked(hWnd,IDC_PATH_ALLOWFLIP);
break;
case IDC_FOLLOW_APPLY:
theFollowUtil.DoFollow();
break;
case IDOK:
theFollowUtil.iu->CloseUtility();
break;
}
break;
case CC_SPINNER_CHANGE: {
ISpinnerControl *spin = (ISpinnerControl*)lParam;
switch (LOWORD(wParam)) {
case IDC_FOLLOW_BANKSPIN:
theFollowUtil.bankAmount = FromBankUI(spin->GetFVal());
break;
case IDC_FOLLOW_TRACKSPIN:
theFollowUtil.tracking = FromTrackUI(spin->GetFVal());
break;
case IDC_FOLLOW_STARTSPIN:
theFollowUtil.start = spin->GetIVal();
break;
case IDC_FOLLOW_ENDSPIN:
theFollowUtil.end = spin->GetIVal();
break;
case IDC_FOLLOW_SAMPSPIN:
theFollowUtil.samples = spin->GetIVal();
break;
}
break;
}
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
theFollowUtil.ip->RollupMouseMessage(hWnd,msg,wParam,lParam);
break;
default:
return FALSE;
}
return TRUE;
}
// --- FollowUtil methods -----------------------------------------
FollowUtil::FollowUtil()
{
bank = FALSE;
flip = FALSE;
bankAmount = FromBankUI(0.5f);
tracking = FromTrackUI(0.5f);
start = 0;
end = 16000;
samples = 25;
}
void FollowUtil::BeginEditParams(Interface *ip,IUtil *iu)
{
this->iu = iu;
this->ip = ip;
hPanel = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_FOLLOW_PANEL),
FollowUtilDlgProc,
GetString(IDS_RB_FOLLOWUTIL),
0);
}
void FollowUtil::EndEditParams(Interface *ip,IUtil *iu)
{
this->iu = NULL;
this->ip = NULL;
ip->DeleteRollupPage(hPanel);
hPanel = NULL;
}
void FollowUtil::SelectionSetChanged(Interface *ip,IUtil *iu)
{
SetStates(hPanel);
if (ip->GetSelNodeCount()==1) {
SetDlgItemText(hPanel,IDC_SEL_NAME,ip->GetSelNode(0)->GetName());
} else if (ip->GetSelNodeCount()) {
SetDlgItemText(hPanel,IDC_SEL_NAME,GetString(IDS_RB_MULTISEL));
} else {
SetDlgItemText(hPanel,IDC_SEL_NAME,GetString(IDS_RB_NONESEL));
}
}
void FollowUtil::Init(HWND hWnd)
{
hPanel = hWnd;
CheckDlgButton(hWnd,IDC_PATH_BANK,bank);
CheckDlgButton(hWnd,IDC_PATH_ALLOWFLIP,flip);
ISpinnerControl * spin;
spin = GetISpinner(GetDlgItem(hWnd,IDC_FOLLOW_STARTSPIN));
spin->SetLimits(TIME_NegInfinity,TIME_PosInfinity,FALSE);
spin->SetScale(10.0f);
spin->LinkToEdit(GetDlgItem(hWnd,IDC_FOLLOW_START),EDITTYPE_TIME);
spin->SetValue(start,FALSE);
ReleaseISpinner(spin);
spin = GetISpinner(GetDlgItem(hWnd,IDC_FOLLOW_ENDSPIN));
spin->SetLimits(TIME_NegInfinity,TIME_PosInfinity,FALSE);
spin->SetScale(10.0f);
spin->LinkToEdit(GetDlgItem(hWnd,IDC_FOLLOW_END),EDITTYPE_TIME);
spin->SetValue(end,FALSE);
ReleaseISpinner(spin);
spin = GetISpinner(GetDlgItem(hWnd,IDC_FOLLOW_SAMPSPIN));
spin->SetLimits(1,999999999,FALSE);
spin->SetScale(0.1f);
spin->LinkToEdit(GetDlgItem(hWnd,IDC_FOLLOW_SAMP),EDITTYPE_INT);
spin->SetValue(samples,FALSE);
ReleaseISpinner(spin);
spin = GetISpinner(GetDlgItem(hWnd,IDC_FOLLOW_BANKSPIN));
spin->SetLimits(-999999999,999999999,FALSE);
spin->SetScale(0.01f);
spin->LinkToEdit(GetDlgItem(hWnd,IDC_FOLLOW_BANK),EDITTYPE_FLOAT);
spin->SetValue(ToBankUI(bankAmount),FALSE);
ReleaseISpinner(spin);
spin = GetISpinner(GetDlgItem(hWnd,IDC_FOLLOW_TRACKSPIN));
spin->SetLimits(0.01f,10.0f,FALSE);
spin->SetScale(0.01f);
spin->LinkToEdit(GetDlgItem(hWnd,IDC_FOLLOW_TRACK),EDITTYPE_FLOAT);
spin->SetValue(ToTrackUI(tracking),FALSE);
ReleaseISpinner(spin);
SelectionSetChanged(ip,iu);
}
void FollowUtil::Destroy(HWND hWnd)
{
hPanel = NULL;
}
void FollowUtil::SetStates(HWND hWnd)
{
if (ip->GetSelNodeCount()) {
EnableWindow(GetDlgItem(hPanel,IDC_FOLLOW_APPLY),TRUE);
} else {
EnableWindow(GetDlgItem(hPanel,IDC_FOLLOW_APPLY),FALSE);
}
if (bank) {
EnableWindow(GetDlgItem(hWnd,IDC_FOLLOW_BANKLABEL),TRUE);
EnableWindow(GetDlgItem(hWnd,IDC_FOLLOW_BANKSPIN),TRUE);
EnableWindow(GetDlgItem(hWnd,IDC_FOLLOW_TRACKLABEL),TRUE);
EnableWindow(GetDlgItem(hWnd,IDC_FOLLOW_TRACKSPIN),TRUE);
} else {
EnableWindow(GetDlgItem(hWnd,IDC_FOLLOW_BANKLABEL),FALSE);
EnableWindow(GetDlgItem(hWnd,IDC_FOLLOW_BANKSPIN),FALSE);
EnableWindow(GetDlgItem(hWnd,IDC_FOLLOW_TRACKLABEL),FALSE);
EnableWindow(GetDlgItem(hWnd,IDC_FOLLOW_TRACKSPIN),FALSE);
}
}
Point3 FollowUtil::GetPosition(INode *node,TimeValue t)
{
Matrix3 tm = node->GetNodeTM(t);
return tm.GetTrans();
}
#define DT 1
#define NUMSTEPS 5
Matrix3 FollowUtil::CalcRefFrame(TimeValue t,INode *node)
{
Interval valid;
Matrix3 tm(1);
TimeValue s = start, e = end;
if (s==e) return tm;
if (s>e) {
int temp = e;
e = s;
s = temp;
}
float u = float(t-s)/float(e);
int length = e-s;
Point3 pt0, pt1;
pt0 = GetPosition(node,t-DT);
pt1 = GetPosition(node,t+DT);
Point3 pathNorm(0,0,0);
if (flip) {
// Compute the normal to the plane of the path by sampling points on the path
#define NUM_SAMPLES 20
Point3 v[NUM_SAMPLES], cent(0,0,0);
for (int i=0; i<NUM_SAMPLES; i++) {
TimeValue tt = int((float(i)/float(NUM_SAMPLES))*float(length)+s);
v[i] = GetPosition(node,tt);
cent += v[i];
}
cent /= float(NUM_SAMPLES);
for (i=1; i<NUM_SAMPLES; i++) {
pathNorm += Normalize((v[i]-cent)^(v[i-1]-cent));
}
pathNorm = Normalize(pathNorm);
}
// X
tm.SetRow(0,Normalize(pt1-pt0));
if (flip) {
// Choose Z in the plane of the path
// Z
tm.SetRow(2,Normalize(tm.GetRow(0)^pathNorm));
// Y
tm.SetRow(1,tm.GetRow(2)^tm.GetRow(0));
} else {
// Choose Y in the world XY plane
// Y
tm.SetRow(1,Normalize(Point3(0,0,1)^tm.GetRow(0)));
// Z
tm.SetRow(2,tm.GetRow(0)^tm.GetRow(1));
}
if (bank) {
// Average over NUMSTEPS samples
Point3 pt0, pt1, pt2, v0, v1;
float cv = 0.0f;
u -= float(NUMSTEPS/2+1)*tracking;
if (u+(NUMSTEPS+2)*tracking > 1.0f) u = 1.0f - (NUMSTEPS+2)*tracking;
if (u<0.0f) u=0.0f;
pt1 = GetPosition(node,int(u*length)+s);
u += tracking;
pt2 = GetPosition(node,int(u*length)+s);
u += tracking;
for (int i=0; i<NUMSTEPS; i++) {
pt0 = pt1;
pt1 = pt2;
if (u>1.0f) {
break;
} else {
pt2 = GetPosition(node,int(u*length)+s);
}
v0 = Normalize(pt2-pt1);
v1 = Normalize(pt1-pt0);
v0.z = v1.z = 0.0f; // remove Z component.
cv += (v0^v1).z * bankAmount / Length(pt1-pt0);
u += tracking;
}
if (i) tm.PreRotateX(cv/float(i));
}
return tm;
}
void FollowUtil::DoFollow()
{
theHold.Begin();
SuspendAnimate();
AnimateOn();
for (int j=0; j<ip->GetSelNodeCount(); j++) {
INode *node = ip->GetSelNode(j);
Control *cont=node->GetTMController()->GetRotationController();
if (cont && cont->IsKeyable()) {
cont->DeleteTime(Interval(start,end),TIME_INCLEFT|TIME_INCRIGHT|TIME_NOSLIDE);
for (int i=0; i<=samples; i++) {
TimeValue t = int((float(i)/float(samples))*(end-start)) + start;
Matrix3 tm = CalcRefFrame(t,node);
Quat q(tm);
cont->SetValue(t,&q,1,CTRL_ABSOLUTE);
}
}
}
ResumeAnimate();
theHold.Accept(GetString(IDS_RB_APPLYFOLLOW));
ip->RedrawViews(ip->GetTime());
}
@@ -0,0 +1,753 @@
/**********************************************************************
*<
FILE: indepos.cpp
DESCRIPTION: An independent X, Y, Z position controller
CREATED BY: Rolf Berteig
HISTORY: created 13 June 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "ctrl.h"
#define IPOS_CONTROL_CLASS_ID Class_ID(0x118f7e02,0xffee238a)
#define IPOS_CONTROL_CNAME GetString(IDS_RB_IPOS)
#define IPOINT3_CONTROL_CLASS_ID Class_ID(0x118f7e02,0xfeee238b)
#define IPOINT3_CONTROL_CNAME GetString(IDS_RB_IPOINT3)
#define ICOLOR_CONTROL_CLASS_ID Class_ID(0x118f7c01,0xfeee238a)
#define ICOLOR_CONTROL_CNAME GetString(IDS_RB_ICOLOR)
#define IPOS_X_REF 0
#define IPOS_Y_REF 1
#define IPOS_Z_REF 2
class IPosDlg;
static DWORD subColor[] = {PAINTCURVE_XCOLOR, PAINTCURVE_YCOLOR, PAINTCURVE_ZCOLOR};
class IndePosition : public Control {
public:
Control *posX;
Control *posY;
Control *posZ;
Point3 curval;
Interval ivalid;
static IPosDlg *dlg;
static IObjParam *ip;
static ULONG beginFlags;
static IndePosition *editControl; // The one being edited.
IndePosition(BOOL loading=FALSE);
IndePosition(const IndePosition &ctrl);
~IndePosition();
void Update(TimeValue t);
// Animatable methods
Class_ID ClassID() { return IPOS_CONTROL_CLASS_ID;}
SClass_ID SuperClassID() {return CTRL_POSITION_CLASS_ID;}
void GetClassName(TSTR& s) {s = IPOS_CONTROL_CNAME;}
void DeleteThis() {delete this;}
int IsKeyable() {return 1;}
int NumSubs() {return 3;}
Animatable* SubAnim(int i);
TSTR SubAnimName(int i);
int SubNumToRefNum(int subNum) {return subNum;}
DWORD GetSubAnimCurveColor(int subNum) {return subColor[subNum];}
ParamDimension* GetParamDimension(int i) {return stdWorldDim;}
BOOL AssignController(Animatable *control,int subAnim);
void AddNewKey(TimeValue t,DWORD flags);
int NumKeys();
TimeValue GetKeyTime(int index);
void CopyKeysFromTime(TimeValue src,TimeValue dst,DWORD flags);
BOOL IsKeyAtTime(TimeValue t,DWORD flags);
BOOL GetNextKeyTime(TimeValue t,DWORD flags,TimeValue &nt);
void DeleteKeyAtTime(TimeValue t);
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev );
void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next );
// Reference methods
int NumRefs() { return 3; };
RefTargetHandle GetReference(int i);
void SetReference(int i, RefTargetHandle rtarg);
RefResult NotifyRefChanged(Interval, RefTargetHandle, PartID&, RefMessage);
// Control methods
Control *GetXController() {return posX;}
Control *GetYController() {return posY;}
Control *GetZController() {return posZ;}
void Copy(Control *from);
RefTargetHandle Clone(RemapDir& remap);
BOOL IsLeaf() {return FALSE;}
void GetValue(TimeValue t, void *val, Interval &valid, GetSetMethod method);
void SetValue(TimeValue t, void *val, int commit, GetSetMethod method);
void CommitValue(TimeValue t);
void RestoreValue(TimeValue t);
};
IPosDlg *IndePosition::dlg = NULL;
IObjParam *IndePosition::ip = NULL;
ULONG IndePosition::beginFlags = 0;
IndePosition *IndePosition::editControl = NULL;
class IndePoint3 : public IndePosition {
public:
IndePoint3(BOOL loading=FALSE) : IndePosition(loading) {}
SClass_ID SuperClassID() {return CTRL_POINT3_CLASS_ID;}
Class_ID ClassID() { return IPOINT3_CONTROL_CLASS_ID;}
void GetClassName(TSTR& s) {s = IPOINT3_CONTROL_CNAME;}
void GetValue(TimeValue t, void *val, Interval &valid, GetSetMethod method);
RefTargetHandle Clone(RemapDir& remap);
};
class IndeColor : public IndePoint3 {
public:
IndeColor(BOOL loading=FALSE) : IndePoint3(loading) {}
SClass_ID SuperClassID() {return CTRL_POINT3_CLASS_ID;}
Class_ID ClassID() { return ICOLOR_CONTROL_CLASS_ID;}
void GetClassName(TSTR& s) {s = ICOLOR_CONTROL_CNAME;}
ParamDimension* GetParamDimension(int i) {return stdColor255Dim;}
RefTargetHandle Clone(RemapDir& remap);
};
class IPosClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading) {return new IndePosition(loading);}
const TCHAR * ClassName() {return IPOS_CONTROL_CNAME;}
SClass_ID SuperClassID() {return CTRL_POSITION_CLASS_ID;}
Class_ID ClassID() {return IPOS_CONTROL_CLASS_ID;}
const TCHAR* Category() {return _T("");}
};
static IPosClassDesc iposCD;
ClassDesc* GetIPosCtrlDesc() {return &iposCD;}
class IPoint3ClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading) {return new IndePoint3(loading);}
const TCHAR * ClassName() {return IPOINT3_CONTROL_CNAME;}
SClass_ID SuperClassID() {return CTRL_POINT3_CLASS_ID;}
Class_ID ClassID() {return IPOINT3_CONTROL_CLASS_ID;}
const TCHAR* Category() {return _T("");}
};
static IPoint3ClassDesc ipoint3CD;
ClassDesc* GetIPoint3CtrlDesc() {return &ipoint3CD;}
class IColorClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading) {return new IndeColor(loading);}
const TCHAR * ClassName() {return ICOLOR_CONTROL_CNAME;}
SClass_ID SuperClassID() {return CTRL_POINT3_CLASS_ID;}
Class_ID ClassID() {return ICOLOR_CONTROL_CLASS_ID;}
const TCHAR* Category() {return _T("");}
};
static IColorClassDesc icolorCD;
ClassDesc* GetIColorCtrlDesc() {return &icolorCD;}
static BOOL CALLBACK IPosParamDialogProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
static const int editButs[] = {IDC_IPOS_X,IDC_IPOS_Y,IDC_IPOS_Z};
#define EDIT_X 0
#define EDIT_Y 1
#define EDIT_Z 2
#define IPOS_BEGIN 1
#define IPOS_MIDDLE 2
#define IPOS_END 3
class IPosDlg {
public:
IndePosition *cont;
HWND hWnd;
IObjParam *ip;
ICustButton *iEdit[3];
static int cur;
IPosDlg(IndePosition *cont,IObjParam *ip);
~IPosDlg();
void Init();
void EndingEdit(IndePosition *next);
void BeginingEdit(IndePosition *cont,IObjParam *ip,IndePosition *prev);
void SetCur(int c,int code=IPOS_MIDDLE);
void WMCommand(int id, int notify, HWND hCtrl);
};
int IPosDlg::cur = EDIT_X;
IPosDlg::IPosDlg(IndePosition *cont,IObjParam *ip)
{
this->ip = ip;
this->cont = cont;
for (int i=0; i<3; i++) {
iEdit[i] = NULL;
}
TCHAR *name;
if (cont->ClassID()==IPOS_CONTROL_CLASS_ID)
name = GetString(IDS_RB_IPOSPARAMS);
else
if (cont->ClassID()==IPOINT3_CONTROL_CLASS_ID)
name = GetString(IDS_RB_IPOINT3PARAMS);
else name = GetString(IDS_RB_ICOLORPARAMS);
hWnd = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_IPOS_PARAMS),
IPosParamDialogProc,
name,
(LPARAM)this);
ip->RegisterDlgWnd(hWnd);
SetCur(cur,IPOS_BEGIN);
UpdateWindow(hWnd);
}
IPosDlg::~IPosDlg()
{
SetCur(cur,IPOS_END);
for (int i=0; i<3; i++) {
ReleaseICustButton(iEdit[i]);
}
ip->UnRegisterDlgWnd(hWnd);
ip->DeleteRollupPage(hWnd);
hWnd = NULL;
}
void IPosDlg::EndingEdit(IndePosition *next)
{
switch (cur) {
case EDIT_X:
cont->posX->EndEditParams(ip,0,next->posX);
break;
case EDIT_Y:
cont->posY->EndEditParams(ip,0,next->posY);
break;
case EDIT_Z:
cont->posZ->EndEditParams(ip,0,next->posZ);
break;
}
cont = NULL;
ip = NULL;
}
void IPosDlg::BeginingEdit(IndePosition *cont,IObjParam *ip,IndePosition *prev)
{
this->ip = ip;
this->cont = cont;
switch (cur) {
case EDIT_X:
cont->posX->BeginEditParams(ip,BEGIN_EDIT_MOTION,prev->posX);
break;
case EDIT_Y:
cont->posY->BeginEditParams(ip,BEGIN_EDIT_MOTION,prev->posY);
break;
case EDIT_Z:
cont->posZ->BeginEditParams(ip,BEGIN_EDIT_MOTION,prev->posZ);
break;
}
UpdateWindow(hWnd);
}
void IPosDlg::Init()
{
for (int i=0; i<3; i++) {
iEdit[i] = GetICustButton(GetDlgItem(hWnd,editButs[i]));
iEdit[i]->SetType(CBT_CHECK);
}
iEdit[cur]->SetCheck(TRUE);
}
void IPosDlg::SetCur(int c,int code)
{
if (c==cur && code==IPOS_MIDDLE) return;
Control *prev = NULL, *next = NULL;
if (code!=IPOS_END) {
switch (c) {
case EDIT_X:
next = cont->posX;
break;
case EDIT_Y:
next = cont->posY;
break;
case EDIT_Z:
next = cont->posZ;
break;
}
}
if (code!=IPOS_BEGIN) {
switch (cur) {
case EDIT_X:
cont->posX->EndEditParams(ip,END_EDIT_REMOVEUI,next);
prev = cont->posX;
break;
case EDIT_Y:
cont->posY->EndEditParams(ip,END_EDIT_REMOVEUI,next);
prev = cont->posY;
break;
case EDIT_Z:
cont->posZ->EndEditParams(ip,END_EDIT_REMOVEUI,next);
prev = cont->posZ;
break;
}
}
cur = c;
if (code!=IPOS_END) {
switch (cur) {
case EDIT_X:
cont->posX->BeginEditParams(ip,BEGIN_EDIT_MOTION,prev);
break;
case EDIT_Y:
cont->posY->BeginEditParams(ip,BEGIN_EDIT_MOTION,prev);
break;
case EDIT_Z:
cont->posZ->BeginEditParams(ip,BEGIN_EDIT_MOTION,prev);
break;
}
}
}
void IPosDlg::WMCommand(int id, int notify, HWND hCtrl)
{
switch (id) {
case IDC_IPOS_X:
SetCur(0);
iEdit[0]->SetCheck(TRUE);
iEdit[1]->SetCheck(FALSE);
iEdit[2]->SetCheck(FALSE);
break;
case IDC_IPOS_Y:
SetCur(1);
iEdit[0]->SetCheck(FALSE);
iEdit[1]->SetCheck(TRUE);
iEdit[2]->SetCheck(FALSE);
break;
case IDC_IPOS_Z:
SetCur(2);
iEdit[0]->SetCheck(FALSE);
iEdit[1]->SetCheck(FALSE);
iEdit[2]->SetCheck(TRUE);
break;
}
}
static BOOL CALLBACK IPosParamDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
IPosDlg *dlg = (IPosDlg*)GetWindowLong(hDlg,GWL_USERDATA);
switch (message) {
case WM_INITDIALOG:
dlg = (IPosDlg*)lParam;
SetWindowLong(hDlg,GWL_USERDATA,lParam);
dlg->hWnd = hDlg;
dlg->Init();
break;
case WM_COMMAND:
dlg->WMCommand(LOWORD(wParam),HIWORD(wParam),(HWND)lParam);
break;
case WM_LBUTTONDOWN:case WM_LBUTTONUP: case WM_MOUSEMOVE:
dlg->ip->RollupMouseMessage(hDlg,message,wParam,lParam);
break;
default:
return FALSE;
}
return TRUE;
}
IndePosition::IndePosition(const IndePosition &ctrl)
{
posX = NULL;
posY = NULL;
posZ = NULL;
if (ctrl.posX) {
ReplaceReference(IPOS_X_REF,ctrl.posX);
} else {
ReplaceReference(IPOS_X_REF,NewDefaultFloatController());
}
if (ctrl.posY) {
ReplaceReference(IPOS_Y_REF,ctrl.posY);
} else {
ReplaceReference(IPOS_Y_REF,NewDefaultFloatController());
}
if (ctrl.posZ) {
ReplaceReference(IPOS_Z_REF,ctrl.posZ);
} else {
ReplaceReference(IPOS_Z_REF,NewDefaultFloatController());
}
curval = ctrl.curval;
ivalid = ctrl.ivalid;
}
IndePosition::IndePosition(BOOL loading)
{
posX = NULL;
posY = NULL;
posZ = NULL;
if (!loading) {
ReplaceReference(IPOS_X_REF,NewDefaultFloatController());
ReplaceReference(IPOS_Y_REF,NewDefaultFloatController());
ReplaceReference(IPOS_Z_REF,NewDefaultFloatController());
ivalid = FOREVER;
curval = Point3(0,0,0);
} else {
ivalid.SetEmpty();
}
}
RefTargetHandle IndePoint3::Clone(RemapDir& remap)
{
IndePoint3 *pos = new IndePoint3(TRUE);
pos->ReplaceReference(IPOS_X_REF, remap.CloneRef(posX));
pos->ReplaceReference(IPOS_Y_REF, remap.CloneRef(posY));
pos->ReplaceReference(IPOS_Z_REF, remap.CloneRef(posZ));
return pos;
}
RefTargetHandle IndeColor::Clone(RemapDir& remap)
{
IndeColor *pos = new IndeColor(TRUE);
pos->ReplaceReference(IPOS_X_REF, remap.CloneRef(posX));
pos->ReplaceReference(IPOS_Y_REF, remap.CloneRef(posY));
pos->ReplaceReference(IPOS_Z_REF, remap.CloneRef(posZ));
return pos;
}
RefTargetHandle IndePosition::Clone(RemapDir& remap)
{
IndePosition *pos = new IndePosition(TRUE);
pos->ReplaceReference(IPOS_X_REF, remap.CloneRef(posX));
pos->ReplaceReference(IPOS_Y_REF, remap.CloneRef(posY));
pos->ReplaceReference(IPOS_Z_REF, remap.CloneRef(posZ));
return pos;
}
IndePosition::~IndePosition()
{
DeleteAllRefsFromMe();
}
void IndePosition::Copy(Control *from)
{
if (from->ClassID()==ClassID()) {
IndePosition *ctrl = (IndePosition*)from;
ReplaceReference(IPOS_X_REF,ctrl->posX);
ReplaceReference(IPOS_Y_REF,ctrl->posY);
ReplaceReference(IPOS_Z_REF,ctrl->posZ);
curval = ctrl->curval;
ivalid = ctrl->ivalid;
} else {
Point3 v;
Interval iv;
int num;
if (num=from->NumKeys()) {
SuspendAnimate();
AnimateOn();
for (int i=0; i<num; i++) {
TimeValue t = from->GetKeyTime(i);
from->GetValue(t,&v,iv);
SetValue(t,&v,TRUE,CTRL_ABSOLUTE);
}
ResumeAnimate();
} else {
from->GetValue(0,&v,ivalid);
SetValue(0,&v,TRUE,CTRL_ABSOLUTE);
}
}
NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
}
void IndePosition::Update(TimeValue t)
{
if (!ivalid.InInterval(t)) {
ivalid = FOREVER;
if (posX) posX->GetValue(t,&curval.x,ivalid);
if (posY) posY->GetValue(t,&curval.y,ivalid);
if (posZ) posZ->GetValue(t,&curval.z,ivalid);
}
}
void IndePosition::SetValue(TimeValue t, void *val, int commit, GetSetMethod method)
{
Point3 *v = (Point3*)val;
if (posX) posX->SetValue(t,&v->x,commit,method);
if (posY) posY->SetValue(t,&v->y,commit,method);
if (posZ) posZ->SetValue(t,&v->z,commit,method);
ivalid.SetEmpty();
NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
}
void IndePosition::GetValue(TimeValue t, void *val, Interval &valid, GetSetMethod method)
{
Update(t);
valid &= ivalid;
if (method==CTRL_RELATIVE) {
Matrix3 *mat = (Matrix3*)val;
mat->PreTranslate(curval);
} else {
*((Point3*)val) = curval;
}
}
void IndePoint3::GetValue(TimeValue t, void *val, Interval &valid, GetSetMethod method)
{
Update(t);
valid &= ivalid;
if (method==CTRL_RELATIVE) {
*((Point3*)val) += curval;
} else {
*((Point3*)val) = curval;
}
}
void IndePosition::CommitValue(TimeValue t)
{
if (posX) posX->CommitValue(t);
if (posY) posY->CommitValue(t);
if (posZ) posZ->CommitValue(t);
}
void IndePosition::RestoreValue(TimeValue t)
{
if (posX) posX->RestoreValue(t);
if (posY) posY->RestoreValue(t);
if (posZ) posZ->RestoreValue(t);
}
RefTargetHandle IndePosition::GetReference(int i)
{
switch (i) {
case IPOS_X_REF: return posX;
case IPOS_Y_REF: return posY;
case IPOS_Z_REF: return posZ;
default: return NULL;
}
}
void IndePosition::SetReference(int i, RefTargetHandle rtarg)
{
switch (i) {
case IPOS_X_REF: posX = (Control*)rtarg; break;
case IPOS_Y_REF: posY = (Control*)rtarg; break;
case IPOS_Z_REF: posZ = (Control*)rtarg; break;
}
}
Animatable* IndePosition::SubAnim(int i)
{
return GetReference(i);
}
TSTR IndePosition::SubAnimName(int i)
{
if (ClassID()==IPOS_CONTROL_CLASS_ID) {
switch (i) {
case IPOS_X_REF: return GetString(IDS_RB_XPOSITION);
case IPOS_Y_REF: return GetString(IDS_RB_YPOSITION);
case IPOS_Z_REF: return GetString(IDS_RB_ZPOSITION);
default: return _T("");
}
} else
if (ClassID()==IPOINT3_CONTROL_CLASS_ID) {
switch (i) {
case IPOS_X_REF: return _T("X");
case IPOS_Y_REF: return _T("Y");
case IPOS_Z_REF: return _T("Z");
default: return _T("");
}
} else {
switch (i) {
case IPOS_X_REF: return _T("R");
case IPOS_Y_REF: return _T("G");
case IPOS_Z_REF: return _T("B");
default: return _T("");
}
}
}
RefResult IndePosition::NotifyRefChanged(
Interval iv,
RefTargetHandle hTarg,
PartID& partID,
RefMessage msg)
{
switch (msg) {
case REFMSG_CHANGE:
ivalid.SetEmpty();
break;
case REFMSG_TARGET_DELETED:
if (posX == hTarg) posX = NULL;
if (posY == hTarg) posY = NULL;
if (posZ == hTarg) posZ = NULL;
break;
case REFMSG_GET_CONTROL_DIM: {
ParamDimension **dim = (ParamDimension **)partID;
assert(dim);
*dim = stdWorldDim;
}
}
return REF_SUCCEED;
}
BOOL IndePosition::AssignController(Animatable *control,int subAnim)
{
switch (subAnim) {
case IPOS_X_REF:
ReplaceReference(IPOS_X_REF,(RefTargetHandle)control);
break;
case IPOS_Y_REF:
ReplaceReference(IPOS_Y_REF,(RefTargetHandle)control);
break;
case IPOS_Z_REF:
ReplaceReference(IPOS_Z_REF,(RefTargetHandle)control);
break;
}
NotifyDependents(FOREVER,0,REFMSG_CONTROLREF_CHANGE,TREE_VIEW_CLASS_ID,FALSE);
NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
return TRUE;
}
void IndePosition::AddNewKey(TimeValue t,DWORD flags)
{
if (posX) posX->AddNewKey(t,flags);
if (posY) posY->AddNewKey(t,flags);
if (posZ) posZ->AddNewKey(t,flags);
}
int IndePosition::NumKeys()
{
int num = 0;
if (posX) num += posX->NumKeys();
if (posY) num += posY->NumKeys();
if (posZ) num += posZ->NumKeys();
return num;
}
TimeValue IndePosition::GetKeyTime(int index)
{
int onum,num = 0;
if (posX) num += posX->NumKeys();
if (index < num) return posX->GetKeyTime(index);
onum = num;
if (posY) num += posY->NumKeys();
if (index < num) return posY->GetKeyTime(index-onum);
onum = num;
if (posZ) num += posZ->NumKeys();
if (index < num) return posZ->GetKeyTime(index-onum);
return 0;
}
void IndePosition::CopyKeysFromTime(TimeValue src,TimeValue dst,DWORD flags)
{
if (posX) posX->CopyKeysFromTime(src,dst,flags);
if (posY) posY->CopyKeysFromTime(src,dst,flags);
if (posZ) posZ->CopyKeysFromTime(src,dst,flags);
}
BOOL IndePosition::IsKeyAtTime(TimeValue t,DWORD flags)
{
if (posX && posX->IsKeyAtTime(t,flags)) return TRUE;
if (posY && posY->IsKeyAtTime(t,flags)) return TRUE;
if (posZ && posZ->IsKeyAtTime(t,flags)) return TRUE;
return FALSE;
}
void IndePosition::DeleteKeyAtTime(TimeValue t)
{
if (posX) posX->DeleteKeyAtTime(t);
if (posY) posY->DeleteKeyAtTime(t);
if (posZ) posZ->DeleteKeyAtTime(t);
}
BOOL IndePosition::GetNextKeyTime(TimeValue t,DWORD flags,TimeValue &nt)
{
TimeValue at,tnear;
BOOL tnearInit = FALSE;
if (posX && posX->GetNextKeyTime(t,flags,at)) {
if (!tnearInit) {
tnear = at;
tnearInit = TRUE;
} else
if (ABS(at-t) < ABS(tnear-t)) tnear = at;
}
if (posY && posY->GetNextKeyTime(t,flags,at)) {
if (!tnearInit) {
tnear = at;
tnearInit = TRUE;
} else
if (ABS(at-t) < ABS(tnear-t)) tnear = at;
}
if (posZ && posZ->GetNextKeyTime(t,flags,at)) {
if (!tnearInit) {
tnear = at;
tnearInit = TRUE;
} else
if (ABS(at-t) < ABS(tnear-t)) tnear = at;
}
if (tnearInit) {
nt = tnear;
return TRUE;
} else {
return FALSE;
}
}
void IndePosition::BeginEditParams(
IObjParam *ip, ULONG flags,Animatable *prev)
{
this->ip = ip;
if (dlg) {
dlg->BeginingEdit(this,ip,(IndePosition*)prev);
} else {
dlg = new IPosDlg(this,ip);
}
}
void IndePosition::EndEditParams(
IObjParam *ip, ULONG flags,Animatable *next)
{
IndePosition *cont=NULL;
if (next && next->ClassID()==ClassID()) {
cont = (IndePosition*)next;
}
if (dlg) {
if (cont) {
dlg->EndingEdit(cont);
} else {
delete dlg;
dlg = NULL;
}
}
}
@@ -0,0 +1,708 @@
/**********************************************************************
*<
FILE: linkctrl.cpp
DESCRIPTION: An animated link controller
CREATED BY: Rolf Berteig
HISTORY: 1/25/97
*> Copyright (c) 1996, All Rights Reserved.
**********************************************************************/
#include "ctrl.h"
#include "units.h"
#include "istdplug.h"
#define LINKCTRL_NAME GetString(IDS_RB_LINKCTRL)
class LinkCtrl;
class PickLinkMode :
public PickModeCallback,
public PickNodeCallback {
public:
LinkCtrl *cont;
PickLinkMode(LinkCtrl *c) {cont=c;}
BOOL HitTest(IObjParam *ip,HWND hWnd,ViewExp *vpt,IPoint2 m,int flags);
BOOL Pick(IObjParam *ip,ViewExp *vpt);
void EnterMode(IObjParam *ip);
void ExitMode(IObjParam *ip);
BOOL RightClick(IObjParam *ip,ViewExp *vpt) {return TRUE;}
BOOL Filter(INode *node);
PickNodeCallback *GetFilter() {return this;}
};
class LinkCtrl : public ILinkCtrl {
public:
Control *tmControl; // ref 0
Tab<INode*> nodes; // ref 1-n
Tab<TimeValue> times;
static HWND hWnd;
static IObjParam *ip;
static LinkCtrl *editCont;
static ISpinnerControl *iTime;
static ICustButton *iPickOb, *iDelOb;
static PickLinkMode *pickLinkMode;
static BOOL valid;
LinkCtrl(BOOL loading=FALSE);
// Animatable methods
void DeleteThis() {delete this;}
Class_ID ClassID() {return LINKCTRL_CLASSID;}
SClass_ID SuperClassID() {return CTRL_MATRIX3_CLASS_ID;}
void GetClassName(TSTR& s) {s = LINKCTRL_NAME;}
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip, ULONG flags,Animatable *next);
int NumSubs() {return 1;}
Animatable* SubAnim(int i) {return tmControl;}
TSTR SubAnimName(int i) {return GetString(IDS_RB_TRANSFORM);}
// Reference methods
RefResult NotifyRefChanged(Interval, RefTargetHandle, PartID&, RefMessage);
IOResult Save(ISave *isave);
IOResult Load(ILoad *iload);
RefTargetHandle Clone(RemapDir &remap = NoRemap());
int NumRefs() {return 1+nodes.Count();}
RefTargetHandle GetReference(int i);
void SetReference(int i, RefTargetHandle rtarg);
BOOL AssignController(Animatable *control,int subAnim);
// Control methods
void Copy(Control *from);
BOOL IsLeaf() {return FALSE;}
void CommitValue(TimeValue t) {}
void RestoreValue(TimeValue t) {}
void GetValue(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE);
void SetValue(TimeValue t, void *val, int commit=1, GetSetMethod method=CTRL_ABSOLUTE);
BOOL InheritsParentTransform() {return FALSE;}
BOOL CanInstanceController() {return FALSE;}
// Animatable methods
void CopyKeysFromTime(TimeValue src,TimeValue dst,DWORD flags) {tmControl->CopyKeysFromTime(src,dst,flags);}
BOOL IsKeyAtTime(TimeValue t,DWORD flags) {return tmControl->IsKeyAtTime(t,flags);}
BOOL GetNextKeyTime(TimeValue t,DWORD flags,TimeValue &nt) {return tmControl->GetNextKeyTime(t,flags,nt);}
int GetKeyTimes(Tab<TimeValue> &times,Interval range,DWORD flags) {return tmControl->GetKeyTimes(times,range,flags);}
int GetKeySelState(BitArray &sel,Interval range,DWORD flags) {return tmControl->GetKeySelState(sel,range,flags);}
Control *GetPositionController() {return tmControl->GetPositionController();}
Control *GetRotationController() {return tmControl->GetRotationController();}
Control *GetScaleController() {return tmControl->GetScaleController();}
BOOL SetPositionController(Control *c) {return tmControl->SetPositionController(c);}
BOOL SetRotationController(Control *c) {return tmControl->SetRotationController(c);}
BOOL SetScaleController(Control *c) {return tmControl->SetScaleController(c);}
void MapKeys(TimeMap *map,DWORD flags);
// From ILinkCtrl
int GetParentCount() {return nodes.Count();}
TimeValue GetLinkTime(int i) {return times[i];}
void SetLinkTime(int i,TimeValue t) {SetTime(t,i);}
void LinkTimeChanged() {SortNodes(-1);}
// Local methods
Matrix3 GetParentTM(TimeValue t,Interval *valid=NULL);
Matrix3 CompTM(TimeValue t, int i);
void AddNewLink(INode *node,TimeValue t);
void DeleteLink(int i);
void SetTime(TimeValue t,int i);
void SortNodes(int sel);
void SetupDialog(HWND hWnd);
void DestroyDialog();
void SetupList(int sel=-1);
void ListSelChanged();
void Invalidate();
void Update();
};
class LinksRestore : public RestoreObj {
public:
LinkCtrl *cont;
Tab<INode*> unodes;
Tab<INode*> rnodes;
Tab<TimeValue> utimes;
Tab<TimeValue> rtimes;
LinksRestore(LinkCtrl *c) {
cont = c;
unodes = cont->nodes;
utimes = cont->times;
}
void Restore(int isUndo) {
if (isUndo) {
rnodes = cont->nodes;
rtimes = cont->times;
}
cont->nodes = unodes;
cont->times = utimes;
cont->NotifyDependents(FOREVER,0,REFMSG_CHANGE);
cont->NotifyDependents(FOREVER,0,REFMSG_SUBANIM_STRUCTURE_CHANGED);
cont->Invalidate();
}
void Redo() {
cont->nodes = rnodes;
cont->times = rtimes;
cont->NotifyDependents(FOREVER,0,REFMSG_CHANGE);
cont->NotifyDependents(FOREVER,0,REFMSG_SUBANIM_STRUCTURE_CHANGED);
cont->Invalidate();
}
void EndHold() {cont->ClearAFlag(A_HELD);}
};
//--- Class Descriptor ----------------------------------------------
HWND LinkCtrl::hWnd = NULL;
IObjParam *LinkCtrl::ip = NULL;
LinkCtrl *LinkCtrl::editCont = NULL;
ISpinnerControl *LinkCtrl::iTime = NULL;
ICustButton *LinkCtrl::iPickOb = NULL;
ICustButton *LinkCtrl::iDelOb = NULL;
PickLinkMode *LinkCtrl::pickLinkMode = NULL;
BOOL LinkCtrl::valid = FALSE;
class LinkCtrlClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading) {return new LinkCtrl(loading);}
const TCHAR * ClassName() {return LINKCTRL_NAME;}
SClass_ID SuperClassID() {return CTRL_MATRIX3_CLASS_ID; }
Class_ID ClassID() {return LINKCTRL_CLASSID;}
const TCHAR* Category() {return _T("");}
};
static LinkCtrlClassDesc linkCtrlCD;
ClassDesc* GetLinkCtrlDesc() {return &linkCtrlCD;}
BOOL CALLBACK LinkParamDialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
//--- LinkCtrl methods -----------------------------------------------
LinkCtrl::LinkCtrl(BOOL loading)
{
tmControl = NULL;
if (!loading) {
Control *cont;
ClassDesc *desc = GetDefaultController(CTRL_MATRIX3_CLASS_ID);
if (desc && desc->ClassID()==ClassID()) {
cont = (Control*)CreateInstance(CTRL_MATRIX3_CLASS_ID, Class_ID(PRS_CONTROL_CLASS_ID,0));
} else {
cont = NewDefaultMatrix3Controller();
}
ReplaceReference(0,cont);
}
}
void LinkCtrl::BeginEditParams(
IObjParam *ip, ULONG flags,Animatable *prev)
{
if (flags&BEGIN_EDIT_MOTION) {
this->ip = ip;
editCont = this;
hWnd = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_LINK_PARAMS),
LinkParamDialogProc,
GetString(IDS_RB_LINKPARAMS),
(LPARAM)this);
pickLinkMode = new PickLinkMode(this);
tmControl->BeginEditParams(ip,flags,NULL);
}
}
void LinkCtrl::EndEditParams(
IObjParam *ip, ULONG flags,Animatable *next)
{
if (editCont) {
ip->ClearPickMode();
tmControl->EndEditParams(ip,flags,NULL);
ip->DeleteRollupPage(hWnd);
hWnd = NULL;
ip = NULL;
editCont = NULL;
delete pickLinkMode;
pickLinkMode = NULL;
}
}
RefResult LinkCtrl::NotifyRefChanged(
Interval iv, RefTargetHandle hTarg,
PartID& partID, RefMessage msg)
{
switch (msg) {
case REFMSG_TARGET_DELETED: {
for (int i=nodes.Count()-1; i>=0; i--) {
if (nodes[i]==hTarg) DeleteLink(i);
}
break;
}
}
return REF_SUCCEED;
}
#define LINKCOUNT_CHUNK 0x0100
#define TIMES_CHUNK 0x0110
IOResult LinkCtrl::Save(ISave *isave)
{
ULONG nb;
int ct = nodes.Count();
isave->BeginChunk(LINKCOUNT_CHUNK);
isave->Write(&ct,sizeof(ct),&nb);
isave->EndChunk();
if (ct) {
isave->BeginChunk(TIMES_CHUNK);
isave->Write(times.Addr(0),sizeof(TimeValue)*ct,&nb);
isave->EndChunk();
}
return IO_OK;
}
IOResult LinkCtrl::Load(ILoad *iload)
{
ULONG nb;
int ct;
IOResult res;
while (IO_OK==(res=iload->OpenChunk())) {
switch (iload->CurChunkID()) {
case LINKCOUNT_CHUNK: {
iload->Read(&ct,sizeof(ct),&nb);
nodes.SetCount(ct);
times.SetCount(ct);
for (int i=0; i<ct; i++) nodes[i] = NULL;
break;
}
case TIMES_CHUNK:
iload->Read(times.Addr(0),sizeof(TimeValue)*ct,&nb);
break;
}
iload->CloseChunk();
if (res!=IO_OK) return res;
}
return IO_OK;
}
RefTargetHandle LinkCtrl::Clone(RemapDir &remap)
{
LinkCtrl *ctrl = new LinkCtrl();
ctrl->ReplaceReference(0,remap.CloneRef(tmControl));
ctrl->nodes.SetCount(nodes.Count());
ctrl->times.SetCount(times.Count());
for (int i=0; i<nodes.Count(); i++) {
ctrl->nodes[i] = NULL;
ctrl->ReplaceReference(i+1,nodes[i]);
ctrl->times[i] = times[i];
}
return ctrl;
}
RefTargetHandle LinkCtrl::GetReference(int i)
{
if (i==0) return tmControl;
return nodes[i-1];
}
void LinkCtrl::SetReference(int i, RefTargetHandle rtarg)
{
if (i==0) tmControl = (Control*)rtarg;
else nodes[i-1] = (INode*)rtarg;
}
BOOL LinkCtrl::AssignController(Animatable *control,int subAnim)
{
if (control->ClassID()==ClassID()) return FALSE;
ReplaceReference(0,(ReferenceTarget*)control);
NotifyDependents(FOREVER,0,REFMSG_CHANGE);
NotifyDependents(FOREVER,0,REFMSG_SUBANIM_STRUCTURE_CHANGED);
return TRUE;
}
void LinkCtrl::Copy(Control *from)
{
if (from->ClassID()==ClassID()) {
LinkCtrl *lc = (LinkCtrl*)from;
ReplaceReference(0,(ReferenceTarget*)lc->tmControl->Clone());
} else {
ReplaceReference(0,(ReferenceTarget*)from->Clone());
}
NotifyDependents(FOREVER,0,REFMSG_CHANGE);
NotifyDependents(FOREVER,0,REFMSG_SUBANIM_STRUCTURE_CHANGED);
}
void LinkCtrl::GetValue(
TimeValue t, void *val, Interval &valid,
GetSetMethod method)
{
Matrix3 *ptm = (Matrix3*)val;
*ptm = GetParentTM(t,&valid);
tmControl->GetValue(t,val,valid,method);
}
void LinkCtrl::SetValue(
TimeValue t, void *val, int commit,
GetSetMethod method)
{
SetXFormPacket *pckt = (SetXFormPacket*)val;
pckt->tmParent = GetParentTM(t);
tmControl->SetValue(t,val,commit,method);
}
Matrix3 LinkCtrl::CompTM(TimeValue t, int i)
{
Matrix3 rtm(1);
if (i) {
// Evaluate the tm of the previous node the instant of the switch
Matrix3 pptm = CompTM(times[i],i-1);
// Evaluate the tm of this node the instant of the switch
Matrix3 ptm = nodes[i]->GetNodeTM(times[i]);
rtm = pptm*Inverse(ptm);
}
return rtm*nodes[i]->GetNodeTM(t);
}
Matrix3 LinkCtrl::GetParentTM(TimeValue t,Interval *valid)
{
if (!nodes.Count()) return Matrix3(1);
for (int i=0; i<nodes.Count(); i++) {
if (times[i]>t) {
if (i) i--;
break;
}
}
if (i>nodes.Count()-1) i = nodes.Count()-1;
// Compute a matrix that adjusts the transitions between links so
// as to maintain continuity
Matrix3 rtm(1);
if (i) {
// Evaluate (recursively) the tm of the previous node the instant of the switch
//Matrix3 pptm = nodes[i-1]->GetNodeTM(times[i]);
Matrix3 pptm = CompTM(times[i],i-1);
// Evaluate the tm of this node the instant of the switch
Matrix3 ptm = nodes[i]->GetNodeTM(times[i]);
rtm = pptm*Inverse(ptm);
}
// Validity is limited to the duration of this link
if (valid) {
Interval iv = FOREVER;
if (i) iv.SetStart(times[i]);
if (i<times.Count()-1) iv.SetEnd(times[i+1]);
*valid &= iv;
}
return rtm*nodes[i]->GetNodeTM(t,valid);
}
void LinkCtrl::AddNewLink(INode *node,TimeValue t)
{
if (theHold.Holding() && !TestAFlag(A_HELD))
theHold.Put(new LinksRestore(this));
if (!nodes.Count()) {
Matrix3 tm(1), ntm = node->GetNodeTM(t), itm(1);
tmControl->GetValue(t,&tm,FOREVER,CTRL_RELATIVE);
tmControl->ChangeParents(t,itm,ntm,tm);
}
for (int i=0; i<nodes.Count(); i++) {
if (times[i]>t) break;
}
nodes.Insert(i,1,&node);
times.Insert(i,1,&t);
MakeRefByID(FOREVER,i+1,node);
NotifyDependents(FOREVER,0,REFMSG_CHANGE);
SetupList(i);
}
void LinkCtrl::DeleteLink(int i)
{
if (nodes.Count()==1) {
TimeValue t = GetCOREInterface()->GetTime();
Matrix3 ptm = GetParentTM(t);
Matrix3 itm(1), tm = ptm;
tmControl->GetValue(t,&tm,FOREVER,CTRL_RELATIVE);
tmControl->ChangeParents(t,ptm,itm,tm);
}
DeleteReference(i+1);
if (theHold.Holding() && !TestAFlag(A_HELD))
theHold.Put(new LinksRestore(this));
nodes.Delete(i,1);
times.Delete(i,1);
NotifyDependents(FOREVER,0,REFMSG_CHANGE);
if (hWnd && editCont==this) SetupList();
}
void LinkCtrl::SetTime(TimeValue t,int i)
{
if (theHold.Holding() && !TestAFlag(A_HELD)) {
theHold.Put(new LinksRestore(this));
SetAFlag(A_HELD);
}
times[i] = t;
SortNodes(i);
NotifyDependents(FOREVER,0,REFMSG_CHANGE);
}
void LinkCtrl::MapKeys(TimeMap *map,DWORD flags)
{
if (theHold.Holding() && !TestAFlag(A_HELD)) {
theHold.Put(new LinksRestore(this));
SetAFlag(A_HELD);
}
for (int i=0; i<times.Count(); i++) {
times[i] = map->map(times[i]);
}
if (hWnd && editCont==this) SetupList();
NotifyDependents(FOREVER,0,REFMSG_CHANGE);
}
static LinkCtrl *theSortCtrl = NULL;
static int __cdecl CompareNodes(const void *a, const void *b)
{
int *aa = (int*)a;
int *bb = (int*)b;
assert(theSortCtrl);
return theSortCtrl->times[*aa] - theSortCtrl->times[*bb];
}
void LinkCtrl::SortNodes(int sel)
{
// Setup a map for a shell sort
Tab<int> map;
map.SetCount(nodes.Count());
for (int i=0; i<map.Count(); i++) map[i] = i;
// Sort
theSortCtrl = this;
map.Sort(CompareNodes);
// Put everything in the right place
Tab<INode*> onodes = nodes;
Tab<TimeValue> otimes = times;
for (i=0; i<nodes.Count(); i++) {
nodes[i] = onodes[map[i]];
times[i] = otimes[map[i]];
}
// Redo the list selecting the node in its new place
if (sel>=0) {
for (i=0; i<map.Count(); i++) {
if (map[i]==sel) {
SetupList(i);
break;
}
}
}
}
//--- UI ------------------------------------------------------------
static BOOL CALLBACK LinkParamDialogProc(
HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
LinkCtrl *cont = (LinkCtrl*)GetWindowLong(hWnd,GWL_USERDATA);
switch (msg) {
case WM_INITDIALOG:
cont = (LinkCtrl*)lParam;
SetWindowLong(hWnd,GWL_USERDATA,lParam);
cont->SetupDialog(hWnd);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_LINK_PICK:
cont->ip->SetPickMode(cont->pickLinkMode);
break;
case IDC_LINK_DELETE: {
int sel = SendDlgItemMessage(hWnd,IDC_LINK_LIST,LB_GETCURSEL,0,0);
if (sel!=LB_ERR) {
theHold.Begin();
cont->DeleteLink(sel);
theHold.Accept(GetString(IDS_RB_DELETELINK));
cont->ip->RedrawViews(cont->ip->GetTime());
}
break;
}
case IDC_LINK_LIST:
if (HIWORD(wParam)==LBN_SELCHANGE) {
cont->ListSelChanged();
}
break;
}
break;
case CC_SPINNER_BUTTONDOWN:
theHold.Begin();
break;
case CC_SPINNER_CHANGE: {
ISpinnerControl *spin = (ISpinnerControl*)lParam;
int sel = SendDlgItemMessage(hWnd,IDC_LINK_LIST,LB_GETCURSEL,0,0);
if (sel!=LB_ERR) cont->SetTime(spin->GetIVal(),sel);
cont->ip->RedrawViews(cont->ip->GetTime());
break;
}
case CC_SPINNER_BUTTONUP:
if (HIWORD(wParam)) {
theHold.Accept(GetString(IDS_RB_SETLINKTIME));
} else {
theHold.Cancel();
}
cont->ip->RedrawViews(cont->ip->GetTime());
break;
case WM_PAINT:
cont->Update();
return FALSE;
case WM_DESTROY:
cont->DestroyDialog();
break;
default:
return FALSE;
}
return TRUE;
}
void LinkCtrl::SetupDialog(HWND hWnd)
{
this->hWnd = hWnd;
iTime = GetISpinner(GetDlgItem(hWnd,IDC_LINK_TIMESPIN));
iTime->SetLimits(TIME_NegInfinity,TIME_PosInfinity,FALSE);
iTime->SetScale(10.0f);
iTime->LinkToEdit(GetDlgItem(hWnd,IDC_LINK_TIME),EDITTYPE_TIME);
iPickOb = GetICustButton(GetDlgItem(hWnd,IDC_LINK_PICK));
iDelOb = GetICustButton(GetDlgItem(hWnd,IDC_LINK_DELETE));
iPickOb->SetType(CBT_CHECK);
iPickOb->SetHighlightColor(GREEN_WASH);
SetupList();
}
void LinkCtrl::DestroyDialog()
{
ReleaseISpinner(iTime);
ReleaseICustButton(iPickOb);
ReleaseICustButton(iDelOb);
iTime = NULL;
iPickOb = NULL;
iDelOb = NULL;
}
void LinkCtrl::SetupList(int sel)
{
if (!hWnd || editCont!=this) return;
int csel = SendDlgItemMessage(hWnd,IDC_LINK_LIST,LB_GETCURSEL,0,0);
if (sel>=0) csel = sel;
SendDlgItemMessage(hWnd,IDC_LINK_LIST,LB_RESETCONTENT,0,0);
for (int i=0; i<nodes.Count(); i++) {
SendDlgItemMessage(hWnd,IDC_LINK_LIST,LB_ADDSTRING,0,
(LPARAM)nodes[i]->GetName());
}
if (csel!=LB_ERR && csel<nodes.Count()) {
SendDlgItemMessage(hWnd,IDC_LINK_LIST,LB_SETCURSEL,csel,0);
}
ListSelChanged();
}
void LinkCtrl::ListSelChanged()
{
int sel = SendDlgItemMessage(hWnd,IDC_LINK_LIST,LB_GETCURSEL,0,0);
if (sel!=LB_ERR) {
iDelOb->Enable();
iTime->Enable();
iTime->SetValue(times[sel],FALSE);
EnableWindow(GetDlgItem(hWnd,IDC_LINK_TIMELABEL),TRUE);
} else {
iDelOb->Disable();
iTime->Disable();
EnableWindow(GetDlgItem(hWnd,IDC_LINK_TIMELABEL),FALSE);
}
}
void LinkCtrl::Invalidate()
{
if (hWnd && editCont==this) {
valid = FALSE;
InvalidateRect(hWnd,NULL,FALSE);
}
}
void LinkCtrl::Update()
{
if (!valid) {
valid = TRUE;
SetupList();
}
}
//--- PickLinkMode ------------------------------------------------
BOOL PickLinkMode::Filter(INode *node)
{
if (node) {
return (node->TestForLoop(FOREVER,cont)==REF_SUCCEED);
}
return FALSE;
}
BOOL PickLinkMode::HitTest(
IObjParam *ip,HWND hWnd,ViewExp *vpt,IPoint2 m,int flags)
{
INode *node = cont->ip->PickNode(hWnd,m);
return node?TRUE:FALSE;
}
BOOL PickLinkMode::Pick(IObjParam *ip,ViewExp *vpt)
{
INode *node = vpt->GetClosestHit();
if (node) {
if (node->TestForLoop(FOREVER,cont)==REF_SUCCEED) {
theHold.Begin();
cont->AddNewLink(node,ip->GetTime());
theHold.Accept(GetString(IDS_RB_ADDLINK));
cont->ip->RedrawViews(cont->ip->GetTime());
}
}
return FALSE;
}
void PickLinkMode::EnterMode(IObjParam *ip)
{cont->iPickOb->SetCheck(TRUE);}
void PickLinkMode::ExitMode(IObjParam *ip)
{cont->iPickOb->SetCheck(FALSE);}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,224 @@
# Microsoft Developer Studio Project File - Name="MaxControls" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=MaxControls - Win32 Armor
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "MaxControls.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "MaxControls.mak" CFG="MaxControls - Win32 Armor"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "MaxControls - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "MaxControls - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "MaxControls - Win32 Profile" (based on "Win32 (x86) Static Library")
!MESSAGE "MaxControls - Win32 Armor" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "MaxControls - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /Zp8 /W3 /GR /O2 /I "..\..\..\Libraries\3dsmax2\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /NODEFAULTLIB
!ELSEIF "$(CFG)" == "MaxControls - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
# ADD CPP /nologo /G6 /Zp8 /MDd /W3 /GR /Zi /Od /I "..\..\..\Libraries\3dsmax2\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "MaxControls - Win32 Profile"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "MaxControls___Win32_Profile"
# PROP BASE Intermediate_Dir "MaxControls___Win32_Profile"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "MaxControls___Win32_Profile"
# PROP Intermediate_Dir "MaxControls___Win32_Profile"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /G6 /Zp4 /W3 /GR /O2 /I "..\..\..\Libraries\3dsmax2\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /Zp8 /W3 /GR /O2 /I "..\..\..\Libraries\3dsmax2\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "MaxControls - Win32 Armor"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "MaxControls___Win32_Armor"
# PROP BASE Intermediate_Dir "MaxControls___Win32_Armor"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "MaxControls___Win32_Armor"
# PROP Intermediate_Dir "MaxControls___Win32_Armor"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /G6 /Zp4 /MDd /W3 /GR /Zi /Od /I "..\..\..\Libraries\3dsmax2\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
# ADD CPP /nologo /G6 /Zp8 /MDd /W3 /GR /Zi /Od /I "..\..\..\Libraries\3dsmax2\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "MaxControls - Win32 Release"
# Name "MaxControls - Win32 Debug"
# Name "MaxControls - Win32 Profile"
# Name "MaxControls - Win32 Armor"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\Attach.cpp
# End Source File
# Begin Source File
SOURCE=.\Boolctrl.cpp
# End Source File
# Begin Source File
SOURCE=.\Control.rc
# End Source File
# Begin Source File
SOURCE=.\Ctrl.cpp
# End Source File
# Begin Source File
SOURCE=.\Eulrctrl.cpp
# End Source File
# Begin Source File
SOURCE=.\Exprctrl.cpp
# End Source File
# Begin Source File
SOURCE=.\Followu.cpp
# End Source File
# Begin Source File
SOURCE=.\Indepos.cpp
# End Source File
# Begin Source File
SOURCE=.\Linkctrl.cpp
# End Source File
# Begin Source File
SOURCE=.\Lodctrl.cpp
# End Source File
# Begin Source File
SOURCE=.\Noizctrl.cpp
# End Source File
# Begin Source File
SOURCE=.\Pathctrl.cpp
# End Source File
# Begin Source File
SOURCE=.\Perlin.cpp
# End Source File
# Begin Source File
SOURCE=.\Surfctrl.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\Ctrl.h
# End Source File
# Begin Source File
SOURCE=.\ExpCtrl.h
# End Source File
# Begin Source File
SOURCE=.\ikslaveclipobject.h
# End Source File
# Begin Source File
SOURCE=.\ikstuff.h
# End Source File
# Begin Source File
SOURCE=.\Noise.h
# End Source File
# Begin Source File
SOURCE=.\Resource.h
# End Source File
# End Group
# End Target
# End Project
@@ -0,0 +1,19 @@
//
// Misc. noise functions from Texturing and Modeling A Procedural Approach
// Perlin, Musgrave...
//
float bias(float a, float b);
float gain(float a, float b);
float noise1(float arg);
float noise2(float vec[]);
float noise3(float vec[]);
float turbulence(float *v, float freq);
int Perm(int v);
#define MAX_OCTAVES 50
double fBm1(double point, double H, double lacunarity, double octaves);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,320 @@
//
// From "Texturing and Modeling A Procedural Approach"
//
// Chapter 6 by Ken Perlin
//
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "noise.h"
#define random() rand()
float bias(float a, float b)
{
return pow((double)a, log((double)b) / log(0.5));
}
float gain(float a, float b)
{
float p = log(1. - b) / log(0.5);
if (a < .001)
return 0.;
else if (a > .999)
return 1.;
if (a < 0.5)
return pow(2 * a, p) / 2;
else
return 1. - pow(2.0 * (1. - a), (double)p) / 2;
}
float noise1(float arg);
float noise2(float vec[]);
float noise3(float vec[]);
float noise(float vec[], int len)
{
switch (len) {
case 0:
return 0.;
case 1:
return noise1(vec[0]);
case 2:
return noise2(vec);
default:
return noise3(vec);
}
}
float turbulence(float *v, float freq)
{
float t, vec[3];
for (t = 0. ; freq >= 1. ; freq /= 2) {
vec[0] = freq * v[0];
vec[1] = freq * v[1];
vec[2] = freq * v[2];
t += fabs(noise3(vec)) / freq;
}
return t;
}
/* noise functions over 1, 2, and 3 dimensions */
#define B 0x100
#define BM 0xff
#define N 0x1000
#define NP 12 /* 2^N */
#define NM 0xfff
static p[B + B + 2];
static float g3[B + B + 2][3];
static float g2[B + B + 2][2];
static float g1[B + B + 2];
static start = 1;
static void init(void);
int Perm(int v)
{
return p[v&BM];
}
#define s_curve(t) ( t * t * (3. - 2. * t) )
#define lerp(t, a, b) ( a + t * (b - a) )
#define setup(i,b0,b1,r0,r1)\
t = vec[i] + N;\
b0 = ((int)t) & BM;\
b1 = (b0+1) & BM;\
r0 = t - (int)t;\
r1 = r0 - 1.;
float noise1(float arg)
{
int bx0, bx1;
float rx0, rx1, sx, t, u, v, vec[1];
vec[0] = arg;
if (start) {
start = 0;
init();
}
setup(0, bx0,bx1, rx0,rx1);
sx = s_curve(rx0);
u = rx0 * g1[ p[ bx0 ] ];
v = rx1 * g1[ p[ bx1 ] ];
return lerp(sx, u, v);
}
float noise2(float vec[2])
{
int bx0, bx1, by0, by1, b00, b10, b01, b11;
float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
register i, j;
if (start) {
start = 0;
init();
}
setup(0, bx0,bx1, rx0,rx1);
setup(1, by0,by1, ry0,ry1);
i = p[ bx0 ];
j = p[ bx1 ];
b00 = p[ i + by0 ];
b10 = p[ j + by0 ];
b01 = p[ i + by1 ];
b11 = p[ j + by1 ];
sx = s_curve(rx0);
sy = s_curve(ry0);
#define at2(rx,ry) ( rx * q[0] + ry * q[1] )
q = g2[ b00 ] ; u = at2(rx0,ry0);
q = g2[ b10 ] ; v = at2(rx1,ry0);
a = lerp(sx, u, v);
q = g2[ b01 ] ; u = at2(rx0,ry1);
q = g2[ b11 ] ; v = at2(rx1,ry1);
b = lerp(sx, u, v);
return lerp(sy, a, b);
}
float noise3(float vec[3])
{
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
register i, j;
if (start) {
start = 0;
init();
}
setup(0, bx0,bx1, rx0,rx1);
setup(1, by0,by1, ry0,ry1);
setup(2, bz0,bz1, rz0,rz1);
i = p[ bx0 ];
j = p[ bx1 ];
b00 = p[ i + by0 ];
b10 = p[ j + by0 ];
b01 = p[ i + by1 ];
b11 = p[ j + by1 ];
t = s_curve(rx0);
sy = s_curve(ry0);
sz = s_curve(rz0);
#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
a = lerp(t, u, v);
q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
b = lerp(t, u, v);
c = lerp(sy, a, b);
q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
a = lerp(t, u, v);
q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
b = lerp(t, u, v);
d = lerp(sy, a, b);
return lerp(sz, c, d);
}
static void normalize2(float v[2])
{
float s;
s = sqrt(v[0] * v[0] + v[1] * v[1]);
v[0] = v[0] / s;
v[1] = v[1] / s;
}
static void normalize3(float v[3])
{
float s;
s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
v[0] = v[0] / s;
v[1] = v[1] / s;
v[2] = v[2] / s;
}
static void init(void)
{
int i, j, k;
srand(0);
for (i = 0 ; i < B ; i++) {
p[i] = i;
g1[i] = (float)((random() % (B + B)) - B) / B;
for (j = 0 ; j < 2 ; j++)
g2[i][j] = (float)((random() % (B + B)) - B) / B;
normalize2(g2[i]);
for (j = 0 ; j < 3 ; j++)
g3[i][j] = (float)((random() % (B + B)) - B) / B;
normalize3(g3[i]);
}
while (--i) {
k = p[i];
p[i] = p[j = random() % B];
p[j] = k;
}
for (i = 0 ; i < B + 2 ; i++) {
p[B + i] = p[i];
g1[B + i] = g1[i];
for (j = 0 ; j < 2 ; j++)
g2[B + i][j] = g2[i][j];
for (j = 0 ; j < 3 ; j++)
g3[B + i][j] = g3[i][j];
}
}
/*
* Procedural fBm evaluated at "point"; returns value stored in "value".
*
* Copyright 1994 F. Kenton Musgrave
*
* Parameters:
* ``H'' is the fractal increment parameter
* ``lacunarity'' is the gap between successive frequencies
* ``octaves'' is the number of frequencies in the fBm
*/
// RB:
// Modified to be evaluated with a scalar.
#define TRUE 1
#define FALSE 0
double
fBm1( double point, double H, double lacunarity, double octaves )
{
static double exponent_array[MAX_OCTAVES+1];
static double lastH;
double value, frequency, remainder, Noise3();
int i;
static int first = TRUE;
/* precompute and store spectral weights */
if (first || H!= lastH) {
lastH = H;
frequency = 1.0;
for (i=0; i<=octaves; i++) {
/* compute weight for each frequency */
exponent_array[i] = pow( frequency, -H );
frequency *= lacunarity;
}
first = FALSE;
}
value = 0.0; /* initialize vars to proper values */
frequency = 1.0;
/* inner loop of spectral construction */
for (i=0; i<octaves; i++) {
value += noise1( point ) * exponent_array[i];
point *= lacunarity;
} /* for */
remainder = octaves - (int)octaves;
if ( remainder ) /* add in ``octaves'' remainder */
/* ``i'' and spatial freq. are preset in loop above */
value += remainder * noise1( point ) * exponent_array[i];
return( value );
} /* fBm() */
@@ -0,0 +1,375 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by control.rc
//
#define IDD_EXPRPARAMS 103
#define IDD_FUNC_LIST 104
#define IDD_SCALAR_ASGN 105
#define IDD_VECTOR_ASGN 106
#define IDD_ATTACH_DIALOG 107
#define IDD_FOLLOW_PANEL 110
#define IDD_PATHPARAMS 123
#define IDD_STDJOINTPARAMS 129
#define IDD_PATHJOINTPARAMS 130
#define IDD_EULER_PARAMS 145
#define IDD_NOISEPARAMS 146
#define IDD_IPOS_PARAMS 147
#define IDD_ATTACH_PARAMS 148
#define IDD_EXPR_DEBUG 149
#define IDD_LINK_PARAMS 150
#define IDD_SURFPARAMS 151
#define IDD_SURFJOINTPARAMS 152
#define IDD_LOD_UTILPARAMS 153
#define IDC_EXPLAIN_NOTATION 1002
#define IDC_PATH_ALLOWFLIP 1003
#define IDC_IPOS_X 1004
#define IDC_PATH_CONSTVEL 1004
#define IDC_IPOS_Y 1005
#define IDC_IPOS_Z 1006
#define IDC_ATTACH_OBNAME 1007
#define IDC_ATTACH_PICKOB 1008
#define IDC_DEBUG_LIST 1008
#define IDC_DEBUG_VALUE 1009
#define IDC_ATTACH_UPDATE 1009
#define IDC_ATTACH_SETPOS 1010
#define IDC_ATTACH_KEYTIME 1011
#define IDC_ATTACH_KEYTIMESPIN 1012
#define IDC_ATTACH_KEYFACE 1013
#define IDC_ATTACH_KEYFACESPIN 1014
#define IDC_ATTACH_KEYA 1015
#define IDC_ATTACH_KEYASPIN 1016
#define IDC_ATTACH_KEYB 1017
#define IDC_ATTACH_KEYBSPIN 1018
#define IDC_ATTACH_FACEPOSGRAPH 1019
#define IDC_ATTACH_KEYTENS 1020
#define IDC_ATTACH_KEYTENSSPIN 1021
#define IDC_ATTACH_KEYCONT 1022
#define IDC_ATTACH_KEYCONTSPIN 1023
#define IDC_ATTACH_KEYBIAS 1024
#define IDC_ATTACH_KEYBIASSPIN 1025
#define IDC_ATTACH_KEYEASETO 1026
#define IDC_ATTACH_KEYEASETOSPIN 1027
#define IDC_ATTACH_KEYEASEFROM 1028
#define IDC_ATTACH_KEYEASEFROMSPIN 1029
#define IDC_SEL_NAME 1029
#define IDC_ATTACH_ALIGN 1030
#define IDC_EXPR_DEBUG 1031
#define IDC_ATTACH_MANUPDATE 1033
#define IDC_LINK_PICK 1035
#define IDC_LINK_LIST 1036
#define IDC_LINK_TIME 1037
#define IDC_LINK_TIMESPIN 1038
#define IDC_LINK_TIMELABEL 1039
#define IDC_LINK_DELETE 1040
#define IDC_SURFNAME 1040
#define IDC_PICKSURF 1041
#define IDC_SURF_U 1042
#define IDC_SURF_USPIN 1043
#define IDC_ALIGN_U 1044
#define IDC_ALIGN_NONE 1045
#define IDC_ALIGN_V 1046
#define IDC_ALIGN_FLIP 1047
#define IDC_EXPR_EDIT 1048
#define IDC_EULER_ORDER 1048
#define IDC_EXPR_EVAL 1049
#define IDC_XAXIS_LABEL 1049
#define IDC_VAR_NAME 1050
#define IDC_YAXIS_LABEL 1050
#define IDC_SCALAR_RB 1051
#define IDC_ZAXIS_LABEL 1051
#define IDC_VECTOR_RB 1052
#define IDC_CREATE_VAR 1053
#define IDC_SCALAR_LIST 1054
#define IDC_VECTOR_LIST 1055
#define IDC_ASGN_CONST 1056
#define IDC_ASGN_CNTRL 1057
#define IDC_FOLLOW_APPLY 1058
#define IDC_ABS_POS 1058
#define IDC_LOD_LIST 1059
#define IDC_FUNCTIONS 1060
#define IDC_LOD_MINLABEL 1060
#define IDC_SAVE 1061
#define IDC_LOD_MIN 1061
#define IDC_LOAD 1062
#define IDC_LOD_MINSPIN 1062
#define IDC_CUR_ASGN 1063
#define IDC_LOD_MAX 1063
#define IDC_FUNC_LIST 1064
#define IDC_LOD_MAXSPIN 1064
#define IDC_DELETE_VAR 1065
#define IDC_LOD_MAXLABEL 1065
#define IDC_DESCRIPTION 1066
#define IDC_LOD_RESET 1066
#define IDC_XTO 1067
#define IDC_LOD_VIEWPORTOBJ 1067
#define IDC_VEC_X 1068
#define IDC_XTOSPIN 1068
#define IDC_LOD_VIEWWIDTH 1068
#define IDC_VEC_Y 1069
#define IDC_XDAMPING 1069
#define IDC_LOD_ADDTOSET 1069
#define IDC_VEC_Z 1070
#define IDC_XDAMPINGSPIN 1070
#define IDC_LOD_DELETEFROMSET 1070
#define IDC_OFFSET 1071
#define IDC_YTO 1071
#define IDC_LOD_CREATENEWSET 1071
#define IDC_CHANGE_OFFSET 1072
#define IDC_YDAMPING 1072
#define IDC_LOD_VIEWWIDTHSPIN 1072
#define IDC_YTOSPIN 1073
#define IDC_LOD_DISPPIXELS 1073
#define IDC_YDAMPINGSPIN 1074
#define IDC_LOD_VIEWHEIGHT 1074
#define IDC_OFFSET_SPIN 1074
#define IDC_ZTO 1075
#define IDC_LOD_VIEWHEIGHTSPIN 1075
#define IDC_ZDAMPING 1076
#define IDC_LOD_DISPPERCENT 1076
#define IDC_ZTOSPIN 1077
#define IDC_LOD_RESETOUTPUT 1077
#define IDC_ZDAMPINGSPIN 1078
#define IDC_XSPRING 1079
#define IDC_XSPRINGSPIN 1080
#define IDC_YSPRING 1081
#define IDC_YSPRINGSPIN 1082
#define IDC_ZSPRING 1083
#define IDC_ZSPRINGSPIN 1084
#define IDC_XSPRINGTENS 1085
#define IDC_XSPRINGTENSSPIN 1086
#define IDC_PICKPATH 1087
#define IDC_YSPRINGTENS 1087
#define IDC_PATHNAME 1088
#define IDC_YSPRINGTENSSPIN 1088
#define IDC_ZSPRINGTENS 1089
#define IDC_PREVKEY 1090
#define IDC_ZSPRINGTENSSPIN 1090
#define IDC_NEXTKEY 1091
#define IDC_KEYNUM 1092
#define IDC_XACTIVE 1099
#define IDC_XLIMITED 1100
#define IDC_XEASE 1101
#define IDC_XFROM 1102
#define IDC_XFROMSPIN 1103
#define IDC_YACTIVE 1104
#define IDC_YLIMITED 1105
#define IDC_YFROM 1106
#define IDC_YEASE 1107
#define IDC_YFROMSPIN 1108
#define IDC_ZACTIVE 1109
#define IDC_ZLIMITED 1110
#define IDC_ZFROM 1111
#define IDC_ZEASE 1112
#define IDC_ZFROMSPIN 1113
#define IDC_EULER_X 1149
#define IDC_EULER_Y 1150
#define IDC_EULER_Z 1151
#define IDC_NOISE_XSTRENGTH 1151
#define IDC_NOISE_XSTRENGTHSPIN 1152
#define IDC_NOISE_FREQ 1153
#define IDC_NOISE_FREQSPIN 1154
#define IDC_NOISE_YSTRENGTH 1155
#define IDC_EXPR_CONST 1156
#define IDC_NOISE_YSTRENGTHSPIN 1156
#define IDC_EXPR_CONST_SPIN 1157
#define IDC_NOISE_SEED 1157
#define IDC_VEC_Z_SPIN 1158
#define IDC_NOISE_SEEDSPIN 1158
#define IDC_VEC_Y_SPIN 1159
#define IDC_NOISE_ZSTRENGTH 1159
#define IDC_NOISE_ZSTRENGTHSPIN 1160
#define IDC_VEC_X_SPIN 1161
#define IDC_NOISE_ROUGH 1161
#define IDC_NOISE_ROUGHSPIN 1162
#define IDC_NOISE_RAMPIN 1163
#define IDC_NOISE_RAMPINSPIN 1164
#define IDC_NOISE_RAMPOUT 1165
#define IDC_NOISE_RAMPOUTSPIN 1166
#define IDC_TCB_GRAPH 1182
#define IDC_PATH_FOLLOW 1200
#define IDC_PATH_BANK 1201
#define IDC_FOLLOW_BANKSPIN 1202
#define IDC_FOLLOW_BANK 1203
#define IDC_FOLLOW_BANKLABEL 1204
#define IDC_FOLLOW_TRACK 1205
#define IDC_FOLLOW_TRACKSPIN 1206
#define IDC_FOLLOW_TRACKLABEL 1207
#define IDC_PATHPERCENT 1208
#define IDC_FOLLOW_START 1208
#define IDC_PATHPERCENTSPIN 1209
#define IDC_FOLLOW_STARTSPIN 1209
#define IDC_NOISE_XSTRENGTHLABEL 1210
#define IDC_FOLLOW_BANKLABEL2 1210
#define IDC_NOISE_YSTRENGTHLABEL 1211
#define IDC_FOLLOW_END 1211
#define IDC_SURF_V 1211
#define IDC_NOISE_ZSTRENGTHLABEL 1212
#define IDC_FOLLOW_ENDSPIN 1212
#define IDC_SURF_VSPIN 1212
#define IDC_NOISE_FRACTAL 1213
#define IDC_FOLLOW_SAMP 1213
#define IDC_NOISE_ROUGHLABEL 1214
#define IDC_FOLLOW_SAMPSPIN 1214
#define IDC_NOISE_GRAPH 1215
#define IDC_NOISE_ZSTRENGTHLABEL2 1216
#define IDC_NOISE_ZSTRENGTHLABEL3 1217
#define IDC_NOISE_XLIM0 1506
#define IDC_NOISE_YLIM0 1507
#define IDC_NOISE_ZLIM0 1508
#define IDC_JP_XFROMLABEL 1534
#define IDC_JP_XTOLABEL 1535
#define IDC_JP_YFROMLABEL 1536
#define IDC_JP_ZFROMLABEL 1537
#define IDC_JP_YTOLABEL 1538
#define IDC_JP_ZTOLABEL 1539
#define IDC_JP_XDAMPINGLABEL 1549
#define IDC_JP_YDAMPINGLABEL 1550
#define IDC_JP_ZDAMPINGLABEL 1551
#define IDC_PATH_X 1607
#define IDC_PATH_Y 1608
#define IDC_PATH_Z 1609
#define IDC_PATH_FLIP 1610
#define IDC_XSPINGBACK 1638
#define IDC_YSPINGBACK 1639
#define IDC_ZSPINGBACK 1640
#define IDS_DB_EXPR_PARSE_ERROR 20280
#define IDS_DB_DUPNAME 20281
#define IDS_DB_CANT_CREATE_VAR 20282
#define IDS_DB_NOSUCH 20283
#define IDS_DB_CANT_CHANGE_OFFSET 20284
#define IDS_DB_NOCURVAR 20285
#define IDS_DB_CANTDELETE 20286
#define IDS_DB_EXPRCNTL 20287
#define IDS_DB_NOTHINGDEL 20288
#define IDS_DB_XPR_FILES 20289
#define IDS_DB_BAD_NAME 20552
#define IDS_DB_POSITION_EXPR 20553
#define IDS_DB_POINT3_EXPR 20554
#define IDS_DB_FLOAT_EXPR 20555
#define IDS_DB_SCALE_EXPR 20556
#define IDS_DB_ROTATION_EXPR 20557
#define IDS_DB_CIRCULAR_DEPENDENCY 20558
#define IDS_DB_CANT_ASSIGN 20559
#define IDS_DB_NEED_VECTOR 20560
#define IDS_DB_NEED_SCALAR 20561
#define IDS_DB_SAVE_EXPR 20562
#define IDS_DB_LOAD_EXPR 20563
#define IDS_RB_PERCENT 30135
#define IDS_RB_PATHPARAMS 30136
#define IDS_RB_NONE 30137
#define IDS_RB_ROTJOINTPARAMS 30148
#define IDS_RB_PATHJOINTPARAMS 30151
#define IDS_RB_STRENGTH 30247
#define IDS_RB_PATH 30532
#define IDS_RB_EULERXYZ 30533
#define IDS_RB_EULERPARAMS 30534
#define IDS_RB_XROTATION 30535
#define IDS_RB_YROTATION 30536
#define IDS_RB_ZROTATION 30537
#define IDS_RB_NOISEFLOAT 30538
#define IDS_RB_NOISEPOSITION 30539
#define IDS_RB_NOISEPOINT3 30540
#define IDS_RB_NOISEROTATION 30541
#define IDS_RB_NOISESCALE 30542
#define IDS_RB_PATHCONTROLLER 30625
#define IDS_RB_ILLEGALPATH 30626
#define IDS_RB_NOISECONTROLTITLE 30655
#define IDS_RB_EXPRESSIONCONTROLTITLE 30656
#define IDS_RB_PICKPATH 30663
#define IDS_DB_FN_SIN 30664
#define IDS_DB_FN_NOISE 30665
#define IDS_DB_FN_IF 30666
#define IDS_DB_FN_MIN 30667
#define IDS_DB_FN_MAX 30668
#define IDS_DB_FN_POW 30669
#define IDS_DB_FN_MOD 30670
#define IDS_DB_FN_DEGTORAD 30671
#define IDS_DB_FN_RADTODEG 30672
#define IDS_DB_FN_COS 30673
#define IDS_DB_FN_TAN 30674
#define IDS_DB_FN_ASIN 30675
#define IDS_DB_FN_ACOS 30676
#define IDS_DB_FN_ATAN 30677
#define IDS_DB_FN_SINH 30678
#define IDS_DB_FN_COSH 30679
#define IDS_DB_FN_TANH 30680
#define IDS_DB_FN_LN 30681
#define IDS_DB_FN_LOG 30682
#define IDS_DB_FN_EXP 30683
#define IDS_DB_FN_SQRT 30684
#define IDS_DB_FN_ABS 30685
#define IDS_DB_FN_CEIL 30686
#define IDS_DB_FN_FLOOR 30687
#define IDS_DB_FN_COMP 30688
#define IDS_DB_FN_UNIT 30689
#define IDS_DB_FN_LENGTH 30690
#define IDS_DB_FN_PI 30691
#define IDS_DB_FN_E 30692
#define IDS_DB_FN_TPS 30693
#define IDS_DB_FN_VIF 30694
#define IDS_RB_NOISESTRENGTH 30695
#define IDS_RB_SETPERCENT 30696
#define IDS_RB_BOOLCONTROL 30697
#define IDS_RB_IPOSPARAMS 30698
#define IDS_RB_IPOS 30699
#define IDS_RB_XPOSITION 30700
#define IDS_RB_YPOSITION 30701
#define IDS_RB_ZPOSITION 30702
#define IDS_RB_ATTACHCONTROL 30703
#define IDS_RB_ATTACHPARAMS 30704
#define IDS_RB_EDITATTACHKEY 30705
#define IDS_RB_ATTACHCONTROLLER 30706
#define IDS_RB_ILLEGALOBJECT 30707
#define IDS_RB_ATTACHTITLE 30708
#define IDS_RB_IPOINT3 30709
#define IDS_RB_IPOINT3PARAMS 30710
#define IDS_RB_ICOLOR 30711
#define IDS_RB_ICOLORPARAMS 30712
#define IDS_RB_LINKCTRL 30713
#define IDS_RB_TRANSFORM 30714
#define IDS_RB_LINKPARAMS 30715
#define IDS_RB_SETLINKTIME 30716
#define IDS_RB_DELETELINK 30717
#define IDS_RB_ADDLINK 30718
#define IDS_RB_FOLLOWUTIL 30719
#define IDS_RB_MULTISEL 30720
#define IDS_RB_NONESEL 30721
#define IDS_RB_APPLYFOLLOW 30722
#define IDS_RB_SURF 30724
#define IDS_RB_U 30725
#define IDS_RB_V 30726
#define IDS_RB_CHANGEUV 30727
#define IDS_RB_SURFPARAMS 30728
#define IDS_RB_SURFJOINTPARAMS 30729
#define IDS_RB_EULERTYPE0 30730
#define IDS_RB_EULERTYPE1 30731
#define IDS_RB_EULERTYPE2 30732
#define IDS_RB_EULERTYPE3 30733
#define IDS_RB_EULERTYPE4 30734
#define IDS_RB_EULERTYPE5 30735
#define IDS_RB_EULERTYPE6 30736
#define IDS_RB_EULERTYPE7 30737
#define IDS_RB_EULERTYPE8 30738
#define IDS_RB_X 30739
#define IDS_RB_Y 30740
#define IDS_RB_Z 30741
#define IDS_RB_XAXIS 30742
#define IDS_RB_YAXIS 30743
#define IDS_RB_ZAXIS 30744
#define IDS_RB_EULERNAME 30745
#define IDS_RB_LODCONTROL 30746
#define IDS_RB_LODUTILITU 30747
#define IDS_RB_LODSAMEPARENT 30748
#define IDS_RB_DEFCONTROLLERS 30749
#define IDS_RB_CHANGESTRENGTH 30750
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 109
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1075
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
@@ -0,0 +1,873 @@
/**********************************************************************
*<
FILE: surfctrl.cpp
DESCRIPTION: A controller that moves an object along a surface
CREATED BY: Rolf Berteig
HISTORY: created 2/13/97
*> Copyright (c) 1997, All Rights Reserved.
**********************************************************************/
#include "ctrl.h"
#include "units.h"
#include "interpik.h"
#include "istdplug.h"
#define SURF_CONTROL_CNAME GetString(IDS_RB_SURF)
#define U_REF 0
#define V_REF 1
#define SURF_REF 2
class SurfPosition;
class PickSurfMode :
public PickModeCallback,
public PickNodeCallback {
public:
SurfPosition *cont;
PickSurfMode(SurfPosition *c) {cont=c;}
BOOL HitTest(IObjParam *ip,HWND hWnd,ViewExp *vpt,IPoint2 m,int flags);
BOOL Pick(IObjParam *ip,ViewExp *vpt);
void EnterMode(IObjParam *ip);
void ExitMode(IObjParam *ip);
BOOL RightClick(IObjParam *ip,ViewExp *vpt) {return TRUE;}
BOOL Filter(INode *node);
PickNodeCallback *GetFilter() {return this;}
};
class SurfPosition : public ISurfPosition, public TimeChangeCallback {
public:
Control *uCont, *vCont;
INode *surf;
int align;
BOOL flip;
Point3 curval;
Quat curRot;
Interval ivalid;
static HWND hWnd;
static IObjParam *ip;
static ICustButton *iPick;
static PickSurfMode *pickMode;
static ISpinnerControl *iU, *iV;
static SurfPosition *editCont;
SurfPosition();
~SurfPosition();
// Animatable methods
Class_ID ClassID() {return SURF_CONTROL_CLASSID;}
SClass_ID SuperClassID() { return CTRL_POSITION_CLASS_ID; }
void GetClassName(TSTR& s) {s = SURF_CONTROL_CNAME;}
void DeleteThis() {delete this;}
int IsKeyable() {return 0;}
int NumSubs() {return 2;}
Animatable* SubAnim(int i);
TSTR SubAnimName(int i);
int SubNumToRefNum(int subNum);
ParamDimension* GetParamDimension(int i) {return stdPercentDim;}
BOOL AssignController(Animatable *control,int subAnim);
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip, ULONG flags,Animatable *next);
int SetProperty(ULONG id, void *data);
void *GetProperty(ULONG id);
// Reference methods
int NumRefs() {return 3;};
RefTargetHandle GetReference(int i);
void SetReference(int i, RefTargetHandle rtarg);
RefResult NotifyRefChanged(Interval, RefTargetHandle, PartID&, RefMessage);
RefTargetHandle Clone(RemapDir& remap);
IOResult Save(ISave *isave);
IOResult Load(ILoad *iload);
// Control methods
void Copy(Control *from);
BOOL IsLeaf() {return FALSE;}
void GetValue(TimeValue t, void *val, Interval &valid, GetSetMethod method);
void SetValue(TimeValue t, void *val, int commit, GetSetMethod method) {}
void CommitValue(TimeValue t);
void RestoreValue(TimeValue t);
void EnumIKParams(IKEnumCallback &callback);
BOOL CompDeriv(TimeValue t,Matrix3& ptm,IKDeriv& derivs,DWORD flags);
float IncIKParam(TimeValue t,int index,float delta);
void ClearIKParam(Interval iv,int index);
// TimeChangeCallback methods
void TimeChanged(TimeValue t);
// Local methods
void SetSurface(INode *node);
void SetupDialog(HWND hWnd);
void DestroyDialog();
void UpdateDialog();
void GetUV(TimeValue t,float &u, float &v,Interval *iv=NULL);
Point3 DU(TimeValue t,float u, float v);
Point3 DV(TimeValue t,float u, float v);
Point3 Norm(TimeValue t,float u, float v);
Point3 Pos(TimeValue t,float u, float v,Interval *iv=NULL);
int GetAlign() {return align;}
void SetAlign(int a);
BOOL GetFlip() {return flip;}
void SetFlip(BOOL f);
};
class JointParamsSurf : public JointParams {
public:
JointParamsSurf() : JointParams((DWORD)JNT_POS,2,1.0f) {}
void SpinnerChange(InterpCtrlUI *ui,WORD id,ISpinnerControl *spin,BOOL interactive);
};
//--- ClassDesc and class vars -------------------------------------
class SurfClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading) { return new SurfPosition();}
const TCHAR * ClassName() {return SURF_CONTROL_CNAME;}
SClass_ID SuperClassID() {return CTRL_POSITION_CLASS_ID;}
Class_ID ClassID() {return SURF_CONTROL_CLASSID;}
const TCHAR* Category() {return _T("");}
};
static SurfClassDesc surfCD;
ClassDesc* GetSurfCtrlDesc() {return &surfCD;}
HWND SurfPosition::hWnd = NULL;
IObjParam *SurfPosition::ip = NULL;
ICustButton *SurfPosition::iPick = NULL;
ISpinnerControl *SurfPosition::iU = NULL;
ISpinnerControl *SurfPosition::iV = NULL;
PickSurfMode *SurfPosition::pickMode = NULL;
SurfPosition *SurfPosition::editCont = NULL;
static BOOL CALLBACK SurfParamDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
//--- SurfPosition methods ------------------------------------------
SurfPosition::SurfPosition()
{
uCont = vCont = NULL;
surf = NULL;
ReplaceReference(U_REF,NewDefaultFloatController());
ReplaceReference(V_REF,NewDefaultFloatController());
align = IDC_ALIGN_NONE;
flip = FALSE;
ivalid.SetEmpty();
}
SurfPosition::~SurfPosition()
{
DeleteAllRefsFromMe();
}
Animatable* SurfPosition::SubAnim(int i)
{
switch (i) {
case 0: return uCont; break;
case 1: return vCont; break;
};
return NULL;
}
TSTR SurfPosition::SubAnimName(int i)
{
switch (i) {
case 0: return GetString(IDS_RB_U); break;
case 1: return GetString(IDS_RB_V); break;
}
return _T("");
}
int SurfPosition::SubNumToRefNum(int subNum)
{
switch (subNum) {
case 0: return 0;
case 1: return 1;
default: return -1;
}
}
BOOL SurfPosition::AssignController(
Animatable *control,int subAnim)
{
ReplaceReference(subAnim,(ReferenceTarget*)control);
ivalid.SetEmpty();
NotifyDependents(FOREVER,0,REFMSG_SUBANIM_STRUCTURE_CHANGED);
NotifyDependents(FOREVER,0,REFMSG_CHANGE);
return TRUE;
}
void SurfPosition::BeginEditParams(
IObjParam *ip, ULONG flags,Animatable *prev)
{
this->ip = ip;
editCont = this;
if (flags&BEGIN_EDIT_HIERARCHY) {
if (align!=IDC_ALIGN_NONE) return;
JointParamsSurf *jp = (JointParamsSurf*)GetProperty(PROPID_JOINTPARAMS);
InterpCtrlUI *ui;
if (!jp) {
jp = new JointParamsSurf();
SetProperty(PROPID_JOINTPARAMS,jp);
}
if (prev &&
prev->ClassID()==ClassID() &&
(ui = (InterpCtrlUI*)prev->GetProperty(PROPID_INTERPUI))) {
JointParams *prevjp = (JointParams*)prev->GetProperty(PROPID_JOINTPARAMS);
prevjp->EndDialog(ui);
ui->cont = this;
ui->ip = ip;
prev->SetProperty(PROPID_INTERPUI,NULL);
JointDlgData *jd = (JointDlgData*)GetWindowLong(ui->hParams,GWL_USERDATA);
jd->jp = jp;
jp->InitDialog(ui);
} else {
ui = new InterpCtrlUI(NULL,ip,this);
DWORD f=0;
if (!jp || !jp->RollupOpen()) f = APPENDROLL_CLOSED;
ui->hParams = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_SURFJOINTPARAMS),
JointParamDlgProc,
GetString(IDS_RB_SURFJOINTPARAMS),
(LPARAM)new JointDlgData(ui,jp),f);
}
SetProperty(PROPID_INTERPUI,ui);
} else {
pickMode = new PickSurfMode(this);
hWnd = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_SURFPARAMS),
SurfParamDlgProc,
GetString(IDS_RB_SURFPARAMS),
(LPARAM)this );
ip->RegisterTimeChangeCallback(this);
}
}
void SurfPosition::EndEditParams(
IObjParam *ip, ULONG flags,Animatable *next)
{
editCont = NULL;
this->ip = NULL;
if (next && next->ClassID()==ClassID() && !hWnd) return;
if (hWnd) {
ip->UnRegisterTimeChangeCallback(this);
ip->ClearPickMode();
delete pickMode;
pickMode = NULL;
ip->DeleteRollupPage(hWnd);
hWnd = NULL;
} else {
int index = aprops.FindProperty(PROPID_INTERPUI);
if (index>=0) {
InterpCtrlUI *ui = (InterpCtrlUI*)aprops[index];
if (ui->hParams) {
ip->UnRegisterDlgWnd(ui->hParams);
ip->DeleteRollupPage(ui->hParams);
}
index = aprops.FindProperty(PROPID_INTERPUI);
if (index>=0) {
delete aprops[index];
aprops.Delete(index,1);
}
}
}
}
RefTargetHandle SurfPosition::GetReference(int i)
{
switch (i) {
case U_REF: return uCont;
case V_REF: return vCont;
case SURF_REF: return surf;
}
return NULL;
}
void SurfPosition::SetReference(int i, RefTargetHandle rtarg)
{
switch (i) {
case U_REF: uCont = (Control*)rtarg; break;
case V_REF: vCont = (Control*)rtarg; break;
case SURF_REF: surf = (INode*)rtarg; break;
}
}
RefResult SurfPosition::NotifyRefChanged(
Interval iv, RefTargetHandle hTarg,
PartID &partID, RefMessage msg)
{
switch (msg) {
case REFMSG_CHANGE:
ivalid.SetEmpty();
break;
case REFMSG_TARGET_DELETED:
if (hTarg == surf) {
surf = NULL;
if (hWnd && editCont == this) {
SetWindowText(GetDlgItem(hWnd,IDC_SURFNAME),
GetString(IDS_RB_NONE));
}
}
break;
}
return REF_SUCCEED;
}
void SurfPosition::SetAlign(int a)
{
align = a;
NotifyDependents(FOREVER,0,REFMSG_CHANGE);
}
void SurfPosition::SetFlip(BOOL f)
{
flip = f;
NotifyDependents(FOREVER,0,REFMSG_CHANGE);
}
RefTargetHandle SurfPosition::Clone(RemapDir& remap)
{
SurfPosition *cont = new SurfPosition;
cont->ReplaceReference(U_REF,remap.CloneRef(uCont));
cont->ReplaceReference(V_REF,remap.CloneRef(vCont));
cont->ReplaceReference(SURF_REF,surf);
cont->align = align;
cont->flip = flip;
return cont;
}
#define ALIGN_CHUNK 0x0100
#define FLIP_CHUNK 0x0110
#define JOINTPARAMSURF_CHUNK 0x0200
IOResult SurfPosition::Save(ISave *isave)
{
JointParamsSurf *jp = (JointParamsSurf*)GetProperty(PROPID_JOINTPARAMS);
ULONG nb;
if (jp) {
isave->BeginChunk(JOINTPARAMSURF_CHUNK);
jp->Save(isave);
isave->EndChunk();
}
isave->BeginChunk(ALIGN_CHUNK);
isave->Write(&align,sizeof(align),&nb);
isave->EndChunk();
if (flip) {
isave->BeginChunk(FLIP_CHUNK);
isave->EndChunk();
}
return IO_OK;
}
IOResult SurfPosition::Load(ILoad *iload)
{
ULONG nb;
IOResult res = IO_OK;
while (IO_OK==(res=iload->OpenChunk())) {
switch (iload->CurChunkID()) {
case ALIGN_CHUNK:
res=iload->Read(&align,sizeof(align),&nb);
break;
case JOINTPARAMSURF_CHUNK: {
JointParamsSurf *jp = new JointParamsSurf;
jp->Load(iload);
SetProperty(PROPID_JOINTPARAMS,jp);
break;
}
case FLIP_CHUNK:
flip = TRUE;
break;
}
iload->CloseChunk();
if (res!=IO_OK) return res;
}
return IO_OK;
}
void SurfPosition::Copy(Control *from)
{
if (from->ClassID()==ClassID()) {
SurfPosition *cont = (SurfPosition*)from;
ReplaceReference(U_REF,cont->uCont->Clone());
ReplaceReference(V_REF,cont->vCont->Clone());
ReplaceReference(SURF_REF,cont->surf);
align = cont->align;
flip = cont->flip;
}
}
void SurfPosition::GetUV(
TimeValue t,float &u, float &v,Interval *iv)
{
Interval valid;
if (!iv) iv = &valid;
uCont->GetValue(t,&u,*iv);
vCont->GetValue(t,&v,*iv);
}
Point3 SurfPosition::DU(TimeValue t,float u, float v)
{
return (Pos(t,u+0.01f,v)-Pos(t,u,v))/0.01f;
}
Point3 SurfPosition::DV(TimeValue t,float u, float v)
{
return (Pos(t,u,v+0.01f)-Pos(t,u,v))/0.01f;
}
Point3 SurfPosition::Norm(TimeValue t,float u, float v)
{
Point3 du = DU(t,u,v);
Point3 dv = DV(t,u,v);
return Normalize(du^dv);
}
Point3 SurfPosition::Pos(
TimeValue t,float u, float v,Interval *iv)
{
Interval valid;
if (!iv) iv = &valid;
if (surf) {
ObjectState os = surf->EvalWorldState(0);
return os.obj->GetSurfacePoint(t,u,v,*iv) *
surf->GetObjTMBeforeWSM(t,iv);
} else {
return Point3(0,0,0);
}
}
void SurfPosition::GetValue(
TimeValue t, void *val, Interval &valid,
GetSetMethod method)
{
if (!ivalid.InInterval(t)) {
float u, v;
ivalid = FOREVER;
GetUV(t,u,v,&ivalid);
curval = Pos(t,u,v,&ivalid);
if (align!=IDC_ALIGN_NONE) {
Matrix3 tm(1);
Point3 norm = Norm(t,u,v);
tm.SetRow(2,flip?-norm:norm);
if (align==IDC_ALIGN_U)
tm.SetRow(0,Normalize(DU(t,u,v)));
else tm.SetRow(0,Normalize(DV(t,u,v)));
tm.SetRow(1,Normalize(tm.GetRow(2)^tm.GetRow(0)));
curRot = Quat(tm);
}
}
if (method==CTRL_RELATIVE) {
Matrix3 *mat = (Matrix3*)val;
if (align!=IDC_ALIGN_NONE) {
curRot.MakeMatrix(*mat);
}
mat->SetTrans(curval);
} else {
*((Point3*)val) = curval;
}
valid &= ivalid;
}
void SurfPosition::CommitValue(TimeValue t)
{
uCont->CommitValue(t);
vCont->CommitValue(t);
}
void SurfPosition::RestoreValue(TimeValue t)
{
uCont->RestoreValue(t);
vCont->RestoreValue(t);
}
void SurfPosition::TimeChanged(TimeValue t)
{
UpdateDialog();
}
void SurfPosition::SetSurface(INode *node)
{
ivalid.SetEmpty();
ReplaceReference(SURF_REF,node);
NotifyDependents(FOREVER,0,REFMSG_CHANGE);
UpdateDialog();
}
//--- PickSurfMode methods -----------------------------------------
BOOL PickSurfMode::HitTest(
IObjParam *ip,HWND hWnd,ViewExp *vpt,
IPoint2 m,int flags)
{
INode *node = cont->ip->PickNode(hWnd,m);
return node?TRUE:FALSE;
}
BOOL PickSurfMode::Pick(IObjParam *ip,ViewExp *vpt)
{
INode *node = vpt->GetClosestHit();
if (node) {
cont->SetSurface(node);
ip->RedrawViews(ip->GetTime());
}
return TRUE;
}
void PickSurfMode::EnterMode(IObjParam *ip)
{
cont->iPick->SetCheck(TRUE);
}
void PickSurfMode::ExitMode(IObjParam *ip)
{
cont->iPick->SetCheck(FALSE);
}
BOOL PickSurfMode::Filter(INode *node)
{
if (node) {
ObjectState os = node->EvalWorldState(0);
if (os.obj->IsParamSurface()) return TRUE;
}
return FALSE;
}
//--- UI -------------------------------------------------------------
static BOOL CALLBACK SurfParamDlgProc(
HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
SurfPosition *co = (SurfPosition*)GetWindowLong(hWnd,GWL_USERDATA);
switch (msg) {
case WM_INITDIALOG:
co = (SurfPosition*)lParam;
SetWindowLong(hWnd, GWL_USERDATA, (LONG)co);
co->SetupDialog(hWnd);
break;
case CC_SPINNER_BUTTONDOWN:
theHold.Begin();
break;
case WM_CUSTEDIT_ENTER:
case CC_SPINNER_BUTTONUP:
if (HIWORD(wParam)) {
theHold.Accept(GetString(IDS_RB_CHANGEUV));
} else {
theHold.Cancel();
}
co->ip->RedrawViews(co->ip->GetTime());
break;
case CC_SPINNER_CHANGE: {
float f;
switch (LOWORD(wParam)) {
case IDC_SURF_USPIN:
f = co->iU->GetFVal();
co->uCont->SetValue(co->ip->GetTime(),&f);
break;
case IDC_SURF_VSPIN:
f = co->iV->GetFVal();
co->vCont->SetValue(co->ip->GetTime(),&f);
break;
}
co->ip->RedrawViews(co->ip->GetTime());
break;
}
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_ALIGN_FLIP:
co->flip = IsDlgButtonChecked(hWnd,IDC_ALIGN_FLIP);
co->ivalid.SetEmpty();
co->NotifyDependents(FOREVER,0,REFMSG_CHANGE);
co->ip->RedrawViews(co->ip->GetTime());
break;
case IDC_ALIGN_NONE:
case IDC_ALIGN_U:
case IDC_ALIGN_V:
co->align = LOWORD(wParam);
co->ivalid.SetEmpty();
co->NotifyDependents(FOREVER,0,REFMSG_CHANGE);
co->ip->RedrawViews(co->ip->GetTime());
co->UpdateDialog();
break;
case IDC_PICKSURF:
co->ip->SetPickMode(co->pickMode);
break;
}
break;
case WM_LBUTTONDOWN:case WM_LBUTTONUP: case WM_MOUSEMOVE:
co->ip->RollupMouseMessage(hWnd,msg,wParam,lParam);
return FALSE;
case WM_DESTROY:
co->DestroyDialog();
break;
default:
return FALSE;
}
return TRUE;
}
void SurfPosition::SetupDialog(HWND hWnd)
{
this->hWnd = hWnd;
iPick = GetICustButton(GetDlgItem(hWnd,IDC_PICKSURF));
iPick->SetType(CBT_CHECK);
iPick->SetHighlightColor(GREEN_WASH);
iU = GetISpinner(GetDlgItem(hWnd,IDC_SURF_USPIN));
iU->SetLimits(-999999999.0f,999999999.0f,FALSE);
iU->SetAutoScale();
iU->LinkToEdit(GetDlgItem(hWnd,IDC_SURF_U),EDITTYPE_FLOAT);
iV = GetISpinner(GetDlgItem(hWnd,IDC_SURF_VSPIN));
iV->SetLimits(-999999999.0f,999999999.0f,FALSE);
iV->SetAutoScale();
iV->LinkToEdit(GetDlgItem(hWnd,IDC_SURF_V),EDITTYPE_FLOAT);
UpdateDialog();
}
void SurfPosition::UpdateDialog()
{
TimeValue t = ip->GetTime();
float f;
uCont->GetValue(t,&f,FOREVER);
iU->SetValue(f,FALSE);
vCont->GetValue(t,&f,FOREVER);
iV->SetValue(f,FALSE);
CheckDlgButton(hWnd,align,TRUE);
CheckDlgButton(hWnd,IDC_ALIGN_FLIP,flip);
if (align!=IDC_ALIGN_NONE)
EnableWindow(GetDlgItem(hWnd,IDC_ALIGN_FLIP),TRUE);
else EnableWindow(GetDlgItem(hWnd,IDC_ALIGN_FLIP),FALSE);
if (surf) {
SetWindowText(GetDlgItem(hWnd,IDC_SURFNAME),
surf->GetName());
} else {
SetWindowText(GetDlgItem(hWnd,IDC_SURFNAME),
GetString(IDS_RB_NONE));
}
}
void SurfPosition::DestroyDialog()
{
ReleaseISpinner(iU); iU = NULL;
ReleaseISpinner(iV); iV = NULL;
ReleaseICustButton(iPick); iPick = NULL;
}
//--- IK -----------------------------------------------------------
int SurfPosition::SetProperty(ULONG id, void *data)
{
if (id==PROPID_JOINTPARAMS) {
if (!data) {
int index = aprops.FindProperty(id);
if (index>=0) {
aprops.Delete(index,1);
}
} else {
JointParamsSurf *jp = (JointParamsSurf*)GetProperty(id);
if (jp) {
*jp = *((JointParamsSurf*)data);
delete (JointParamsSurf*)data;
} else {
aprops.Append(1,(AnimProperty**)&data);
}
}
return 1;
} else
if (id==PROPID_INTERPUI) {
if (!data) {
int index = aprops.FindProperty(id);
if (index>=0) {
aprops.Delete(index,1);
}
} else {
InterpCtrlUI *ui = (InterpCtrlUI*)GetProperty(id);
if (ui) {
*ui = *((InterpCtrlUI*)data);
} else {
aprops.Append(1,(AnimProperty**)&data);
}
}
return 1;
} else {
return Animatable::SetProperty(id,data);
}
}
void* SurfPosition::GetProperty(ULONG id)
{
if (id==PROPID_INTERPUI || id==PROPID_JOINTPARAMS) {
int index = aprops.FindProperty(id);
if (index>=0) {
return aprops[index];
} else {
return NULL;
}
} else {
return Animatable::GetProperty(id);
}
}
void JointParamsSurf::SpinnerChange(
InterpCtrlUI *ui,WORD id,ISpinnerControl *spin,
BOOL interactive)
{
float val;
int set = 0;
switch (id) {
case IDC_XFROMSPIN:
val = min[0] = spin->GetFVal()/scale;
set = 1;
break;
case IDC_XTOSPIN:
val = max[0] = spin->GetFVal()/scale;
set = 1;
break;
case IDC_XDAMPINGSPIN:
damping[0] = spin->GetFVal(); break;
case IDC_YFROMSPIN:
val = min[1] = spin->GetFVal()/scale;
set = 2;
break;
case IDC_YTOSPIN:
val = max[1] = spin->GetFVal()/scale;
set = 2;
break;
case IDC_YDAMPINGSPIN:
damping[1] = spin->GetFVal(); break;
}
if (set && interactive) {
SurfPosition *c = (SurfPosition*)ui->cont;
if (set==1)
c->uCont->SetValue(
ui->ip->GetTime(),&val,TRUE,CTRL_ABSOLUTE);
else c->vCont->SetValue(
ui->ip->GetTime(),&val,TRUE,CTRL_ABSOLUTE);
ui->ip->RedrawViews(ui->ip->GetTime(),REDRAW_INTERACTIVE);
}
}
void SurfPosition::EnumIKParams(IKEnumCallback &callback)
{
JointParamsSurf *jp = (JointParamsSurf*)GetProperty(PROPID_JOINTPARAMS);
if (jp && align==IDC_ALIGN_NONE) {
if (jp->Active(0)) callback.proc(this,0);
if (jp->Active(1)) callback.proc(this,1);
}
}
BOOL SurfPosition::CompDeriv(
TimeValue t,Matrix3& ptm,IKDeriv& derivs,DWORD flags)
{
JointParamsSurf *jp = (JointParamsSurf*)GetProperty(PROPID_JOINTPARAMS);
if (!jp || align!=IDC_ALIGN_NONE) return FALSE;
float u, v;
GetUV(t,u,v);
Point3 zero(0,0,0);
if (jp->Active(0)) {
Point3 d = DU(t,u,v);
for (int j=0; j<derivs.NumEndEffectors(); j++) {
if (flags&POSITION_DERIV) {
derivs.DP(d,j);
}
if (flags&ROTATION_DERIV) {
derivs.DR(zero,j);
}
}
derivs.NextDOF();
}
if (jp->Active(1)) {
Point3 d = DV(t,u,v);
for (int j=0; j<derivs.NumEndEffectors(); j++) {
if (flags&POSITION_DERIV) {
derivs.DP(d,j);
}
if (flags&ROTATION_DERIV) {
derivs.DR(zero,j);
}
}
derivs.NextDOF();
}
ptm.SetTrans(Pos(t,u,v));
return TRUE;
}
float SurfPosition::IncIKParam(TimeValue t,int index,float delta)
{
JointParamsSurf *jp = (JointParamsSurf*)GetProperty(PROPID_JOINTPARAMS);
if (fabs(delta) > 0.01f) {
if (delta<0) delta = -0.01f;
else delta = 0.01f;
}
if (jp) {
float u, v;
if (index==0) {
if (jp->Limited(0)) {
uCont->GetValue(t,&u,FOREVER);
}
delta = jp->ConstrainInc(0,u,delta);
uCont->SetValue(t,&delta,FALSE,CTRL_RELATIVE);
} else {
if (jp->Limited(1)) {
vCont->GetValue(t,&v,FOREVER);
}
delta = jp->ConstrainInc(0,v,delta);
vCont->SetValue(t,&delta,FALSE,CTRL_RELATIVE);
}
}
return delta;
}
void SurfPosition::ClearIKParam(Interval iv,int index)
{
uCont->DeleteTime(iv,TIME_INCRIGHT|TIME_NOSLIDE);
vCont->DeleteTime(iv,TIME_INCRIGHT|TIME_NOSLIDE);
}
@@ -0,0 +1,19 @@
#include "Max.h"
#include "plugapi.h"
#define IKSLAVE_CLASSID Class_ID(0xbe380a31,0x310dc9e4)
class IKClipObject; // Sorry, can't show you this
class IKSlave; // Sorry, can't show you this
class IKSlaveClipObject : public IKClipObject
{
public:
DWORD flags;
float min[6], max[6], damping[6], spring[6], stens[6];
IKSlaveClipObject(IKSlave *slave);
SClass_ID SuperClassID() {return CTRL_MATRIX3_CLASS_ID;}
Class_ID ClassID() {return IKSLAVE_CLASSID;}
void DeleteThis() {delete this;}
};
@@ -0,0 +1,48 @@
#include <windows.h>
#include "Max.h"
#include "3dswin.h"
#include "resource.h"
#include "istdplug.h"
// IK stuff
//
// Function name : DCG_GetSolverPosThresh
// Description :
// Return type : float
// Argument : unsigned int *pFromCtrl
__declspec(dllexport) float DCG_GetSolverPosThresh(unsigned int *pFromCtrl);
// Function name : DCG_SetSolverPosThresh
// Description :
// Return type : void
// Argument : unsigned int *pFromCtrl
// Argument : float f
__declspec(dllexport) void DCG_SetSolverPosThresh(unsigned int *pFromCtrl, float f);
// Function name : DCG_GetSolverRotThresh
// Description :
// Return type : float
// Argument : unsigned int *pFromCtrl
__declspec(dllexport) float DCG_GetSolverRotThresh(unsigned int *pFromCtrl);
// Function name : DCG_SetSolverRotThresh
// Description :
// Return type : void
// Argument : unsigned int *pFromCtrl
// Argument : float f
__declspec(dllexport) void DCG_SetSolverRotThresh(unsigned int *pFromCtrl,float f);
// Function name : DCG_GetSolverIterations
// Description :
// Return type : int
// Argument : unsigned int *pFromCtrl
__declspec(dllexport) int DCG_GetSolverIterations(unsigned int *pFromCtrl);
// Function name : DCG_SetSolverIterations
// Description :
// Return type : void
// Argument : unsigned int *pFromCtrl
// Argument : int i
__declspec(dllexport) void DCG_SetSolverIterations(unsigned int *pFromCtrl,int i);