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
@@ -0,0 +1,650 @@
/**********************************************************************
*<
FILE: afregion.cpp
DESCRIPTION: Affect region modifier
CREATED BY: Rolf Berteig
HISTORY: 10/16/96
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#define PBLOCK_REF 0
#define POINT1_REF 1
#define POINT2_REF 2
class AFRMod : public Modifier {
public:
IParamBlock *pblock;
Control *p1, *p2;
BYTE sel[2];
static IObjParam *ip;
static IParamMap *pmapParam;
static AFRMod *editMod;
static MoveModBoxCMode *moveMode;
AFRMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) {s = GetString(IDS_RB_AFRMOD);}
virtual Class_ID ClassID() { return Class_ID(AFFECTREGION_CLASS_ID,0);}
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip,ULONG flags,Animatable *next);
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_AFRMOD);}
int SubNumToRefNum(int subNum);
BOOL AssignController(Animatable *control,int subAnim);
// From modifier
ChannelMask ChannelsUsed() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_SUBSEL_TYPE;}
ChannelMask ChannelsChanged() {return PART_GEOM;}
Class_ID InputType() {return defObjectClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t);
// From BaseObject
int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc);
int Display(TimeValue t, INode* inode, ViewExp *vpt, int flagst, ModContext *mc);
void GetWorldBoundBox(TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc);
void Move( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE );
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
void GetSubObjectCenters(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void GetSubObjectTMs(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void ActivateSubobjSel(int level, XFormModes& modes);
void SelectSubComponent(HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert=FALSE);
void ClearSelection(int selLevel);
void SelectAll(int selLevel);
void InvertSelection(int selLevel);
int NumRefs() {return 3;}
RefTargetHandle GetReference(int i);
void SetReference(int i, RefTargetHandle rtarg);
int NumSubs() {return 3;}
Animatable* SubAnim(int i) {return GetReference(i);}
TSTR SubAnimName(int i);
RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message);
Matrix3 CompMatrix(TimeValue t,INode *inode,ModContext *mc);
};
class AFRDeformer : public Deformer {
public:
float falloff, pinch, bubble;
Point3 p1, p2;
Tab<Point3> *normals;
AFRDeformer(
ModContext &mc, float f, float p, float b,
Point3 pt1, Point3 pt2, Tab<Point3> *n=NULL);
Point3 Map(int i, Point3 p);
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *AFRMod::pmapParam = NULL;
IObjParam *AFRMod::ip = NULL;
AFRMod *AFRMod::editMod = NULL;
MoveModBoxCMode *AFRMod::moveMode = NULL;
class AFRClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new AFRMod; }
const TCHAR * ClassName() { return GetString(IDS_RB_AFRMOD); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(AFFECTREGION_CLASS_ID,0); }
const TCHAR* Category() { return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static AFRClassDesc afrDesc;
extern ClassDesc* GetAFRModDesc() {return &afrDesc;}
//--- Parameter map/block descriptors -------------------------------
#define PB_FALLOFF 0
#define PB_BACKFACE 1
#define PB_PINCH 2
#define PB_BUBBLE 3
//
//
// Parameters
static ParamUIDesc descParam[] = {
// Falloff
ParamUIDesc(
PB_FALLOFF,
EDITTYPE_FLOAT,
IDC_AFR_FALLOFF,IDC_AFR_FALLOFFSPIN,
0.0f,BIGFLOAT,
SPIN_AUTOSCALE),
// Backface
ParamUIDesc(PB_BACKFACE,TYPE_SINGLECHEKBOX,IDC_AFR_BACKFACE),
// Pinch
ParamUIDesc(
PB_PINCH,
EDITTYPE_FLOAT,
IDC_AFR_PINCH,IDC_AFR_PINCHSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// Bubble
ParamUIDesc(
PB_BUBBLE,
EDITTYPE_FLOAT,
IDC_AFR_BUBBLE,IDC_AFR_BUBBLESPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
};
#define PARAMDESC_LENGTH 4
static ParamBlockDescID descVer0[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 }, // Falloff
{ TYPE_INT, NULL, FALSE, 1 }, // Backface
{ TYPE_FLOAT, NULL, TRUE, 2 }, // Pinch
{ TYPE_FLOAT, NULL, TRUE, 3 }, // Bubble
};
#define PBLOCK_LENGTH 4
#define CURRENT_VERSION 0
//--- Affect region mod methods -------------------------------
AFRMod::AFRMod()
{
MakeRefByID(
FOREVER, PBLOCK_REF,
CreateParameterBlock(
descVer0, PBLOCK_LENGTH, CURRENT_VERSION));
p1 = p2 = NULL;
MakeRefByID(FOREVER,POINT1_REF,NewDefaultPoint3Controller());
MakeRefByID(FOREVER,POINT2_REF,NewDefaultPoint3Controller());
sel[0] = sel[1] = 0;
pblock->SetValue(PB_FALLOFF,0,20.0f);
Point3 pt(0,0,25);
p2->SetValue(0,&pt);
}
void AFRMod::BeginEditParams(
IObjParam *ip, ULONG flags,Animatable *prev)
{
this->ip = ip;
editMod = this;
// Add our sub object type
TSTR type1(GetString(IDS_RB_AFRPOINTS));
const TCHAR *ptype[] = {type1};
ip->RegisterSubObjectTypes(ptype, 1);
// Create sub object editing modes.
moveMode = new MoveModBoxCMode(this,ip);
TimeValue t = ip->GetTime();
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_BEGIN_EDIT);
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_MOD_DISPLAY_ON);
SetAFlag(A_MOD_BEING_EDITED);
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGTH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_AFRPARAM),
GetString(IDS_RB_PARAMETERS),
0);
}
void AFRMod::EndEditParams(
IObjParam *ip,ULONG flags,Animatable *next)
{
this->ip = NULL;
editMod = NULL;
TimeValue t = ip->GetTime();
// NOTE: This flag must be cleared before sending the REFMSG_END_EDIT
ClearAFlag(A_MOD_BEING_EDITED);
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_END_EDIT);
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_MOD_DISPLAY_OFF);
ip->DeleteMode(moveMode);
if (moveMode) delete moveMode;
moveMode = NULL;
DestroyCPParamMap(pmapParam);
}
RefTargetHandle AFRMod::Clone(RemapDir& remap)
{
AFRMod *mod = new AFRMod();
mod->ReplaceReference(PBLOCK_REF,pblock->Clone(remap));
mod->ReplaceReference(POINT1_REF,p1->Clone(remap));
mod->ReplaceReference(POINT2_REF,p2->Clone(remap));
return mod;
}
void AFRMod::ModifyObject(
TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
Interval iv = FOREVER;
float f, p, b;
int backface;
Point3 pt1, pt2;
pblock->GetValue(PB_FALLOFF,t,f,iv);
pblock->GetValue(PB_PINCH,t,p,iv);
pblock->GetValue(PB_BUBBLE,t,b,iv);
pblock->GetValue(PB_BACKFACE,t,backface,iv);
p1->GetValue(t,&pt1,iv,CTRL_ABSOLUTE);
p2->GetValue(t,&pt2,iv,CTRL_ABSOLUTE);
if (f==0.0) {
os->obj->UpdateValidity(GEOM_CHAN_NUM,iv);
return;
}
if (backface && os->obj->IsSubClassOf(triObjectClassID)) {
TriObject *tobj = (TriObject*)os->obj;
Mesh &mesh = tobj->mesh;
Tab<Point3> normals;
normals.SetCount(mesh.getNumVerts());
for (int i=0; i<mesh.getNumVerts(); i++) {
normals[i] = Point3(0,0,0);
}
for (i=0; i<mesh.getNumFaces(); i++) {
Point3 norm =
(mesh.verts[mesh.faces[i].v[1]]-mesh.verts[mesh.faces[i].v[0]]) ^
(mesh.verts[mesh.faces[i].v[2]]-mesh.verts[mesh.faces[i].v[1]]);
for (int j=0; j<3; j++) {
normals[mesh.faces[i].v[j]] += norm;
}
}
AFRDeformer deformer(mc,f,p,b,pt1,pt2,&normals);
os->obj->Deform(&deformer, TRUE);
} else {
AFRDeformer deformer(mc,f,p,b,pt1,pt2);
os->obj->Deform(&deformer, TRUE);
}
os->obj->UpdateValidity(GEOM_CHAN_NUM,iv);
}
Interval AFRMod::LocalValidity(TimeValue t)
{
Interval iv = FOREVER;
float v;
Point3 pt;
pblock->GetValue(PB_FALLOFF,t,v,iv);
pblock->GetValue(PB_PINCH,t,v,iv);
pblock->GetValue(PB_BUBBLE,t,v,iv);
p1->GetValue(t,&pt,iv,CTRL_ABSOLUTE);
p2->GetValue(t,&pt,iv,CTRL_ABSOLUTE);
return iv;
}
Matrix3 AFRMod::CompMatrix(TimeValue t,INode *inode,ModContext *mc)
{
Interval iv;
Matrix3 tm(1);
if (mc && mc->tm) tm = Inverse(*(mc->tm));
if (inode) tm = tm * inode->GetObjTMBeforeWSM(t,&iv);
return tm;
}
int AFRMod::HitTest(
TimeValue t, INode* inode,
int type, int crossing, int flags,
IPoint2 *p, ViewExp *vpt, ModContext* mc)
{
GraphicsWindow *gw = vpt->getGW();
Point3 pt;
HitRegion hr;
int savedLimits, res = 0;
Matrix3 tm = CompMatrix(t,inode,mc);
MakeHitRegion(hr,type, crossing,4,p);
gw->setHitRegion(&hr);
gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM);
gw->setTransform(tm);
// Hit test start point
if ((flags&HIT_SELONLY && sel[0]) ||
(flags&HIT_UNSELONLY && !sel[0]) ||
!(flags&(HIT_UNSELONLY|HIT_SELONLY)) ) {
gw->clearHitCode();
p1->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE);
gw->marker(&pt,HOLLOW_BOX_MRKR);
if (gw->checkHitCode()) {
vpt->LogHit(inode, mc, gw->getHitDistance(), 0, NULL);
res = 1;
}
}
// Hit test end point
if ((flags&HIT_SELONLY && sel[1]) ||
(flags&HIT_UNSELONLY && !sel[1]) ||
!(flags&(HIT_UNSELONLY|HIT_SELONLY)) ) {
gw->clearHitCode();
p2->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE);
gw->marker(&pt,HOLLOW_BOX_MRKR);
if (gw->checkHitCode()) {
vpt->LogHit(inode, mc, gw->getHitDistance(), 1, NULL);
res = 1;
}
}
gw->setRndLimits(savedLimits);
return res;
}
int AFRMod::Display(
TimeValue t, INode* inode, ViewExp *vpt,
int flagst, ModContext *mc)
{
GraphicsWindow *gw = vpt->getGW();
Point3 pt[4];
Matrix3 tm = CompMatrix(t,inode,mc);
int savedLimits;
gw->setRndLimits((savedLimits = gw->getRndLimits()) & ~GW_ILLUM);
gw->setTransform(tm);
// Draw start point
if (ip && ip->GetSubObjectLevel() == 1) {
if (sel[0])
gw->setColor(LINE_COLOR, (float)1.0, (float)0.0, (float)0.0);
else //gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
} else {
//gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS));
}
p1->GetValue(t,&pt[0],FOREVER,CTRL_ABSOLUTE);
gw->marker(&pt[0],HOLLOW_BOX_MRKR);
// Draw end point
if (ip && ip->GetSubObjectLevel() == 1) {
if (sel[1])
gw->setColor(LINE_COLOR, (float)1.0, (float)0.0, (float)0.0);
else //gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
} else {
//gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS));
}
p2->GetValue(t,&pt[1],FOREVER,CTRL_ABSOLUTE);
gw->marker(&pt[1],HOLLOW_BOX_MRKR);
// Draw a line inbetween
if (ip && ip->GetSubObjectLevel() == 1) {
//gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
} else {
//gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS));
}
gw->polyline(2, pt, NULL, NULL, 0, NULL);
// Draw arrowhead
Matrix3 vtm;
vpt->GetAffineTM(vtm);
Point3 vz = vtm.GetRow(2) * Inverse(tm);
Point3 dp = (pt[1]-pt[0]);
Point3 v = Normalize(vz^dp) * Length(dp) * 0.2f;
pt[0] = pt[1] - (0.2f*dp) + v;
pt[2] = pt[1] - (0.2f*dp) - v;
gw->polyline(3, pt, NULL, NULL, 0, NULL);
v = Normalize(v^dp) * Length(dp) * 0.2f;
pt[0] = pt[1] - (0.2f*dp) + v;
pt[2] = pt[1] - (0.2f*dp) - v;
gw->polyline(3, pt, NULL, NULL, 0, NULL);
gw->setRndLimits(savedLimits);
return 0;
}
void AFRMod::GetWorldBoundBox(
TimeValue t,INode* inode, ViewExp *vpt,
Box3& box, ModContext *mc)
{
Matrix3 tm = CompMatrix(t,inode,mc);
Point3 pt1, pt2;
box.Init();
p1->GetValue(t,&pt1,FOREVER,CTRL_ABSOLUTE);
box += pt1 * tm;
p2->GetValue(t,&pt2,FOREVER,CTRL_ABSOLUTE);
box += pt2 * tm;
Matrix3 vtm;
vpt->GetAffineTM(vtm);
Point3 vz = vtm.GetRow(2) * Inverse(tm);
Point3 dp = (pt1-pt2);
Point3 v = Normalize(vz^dp) * Length(dp) * 0.2f;
box += (pt1 - (0.2f*dp) + v) * tm;
box += (pt1 - (0.2f*dp) - v) * tm;
v = Normalize(v^dp) * Length(dp) * 0.2f;
box += (pt1 - (0.2f*dp) + v) * tm;
box += (pt1 - (0.2f*dp) - v) * tm;
}
void AFRMod::Move(TimeValue t, Matrix3& partm, Matrix3& tmAxis,
Point3& val, BOOL localOrigin)
{
if (sel[0]) {
p1->SetValue(
t,VectorTransform(tmAxis*Inverse(partm),val),
TRUE,CTRL_RELATIVE);
}
if (sel[1]) {
p2->SetValue(
t,VectorTransform(tmAxis*Inverse(partm),val),
TRUE,CTRL_RELATIVE);
}
}
void AFRMod::GetSubObjectCenters(
SubObjAxisCallback *cb,TimeValue t,
INode *node,ModContext *mc)
{
Matrix3 tm = CompMatrix(t,node,mc);
Point3 pt(0,0,0), p;
int c=0;
if (sel[0]) {
p1->GetValue(t,&p,FOREVER,CTRL_ABSOLUTE);
pt += p;
c++;
}
if (sel[1]) {
p2->GetValue(t,&p,FOREVER,CTRL_ABSOLUTE);
pt += p;
c++;
}
if (c) pt /= float(c);
tm.PreTranslate(pt);
cb->Center(tm.GetTrans(),0);
}
void AFRMod::GetSubObjectTMs(
SubObjAxisCallback *cb,TimeValue t,
INode *node,ModContext *mc)
{
Matrix3 tm = CompMatrix(t,node,mc);
cb->TM(tm,0);
}
void AFRMod::SelectSubComponent(
HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert)
{
//if (theHold.Holding()) theHold.Put(new SelRestore(this));
while (hitRec) {
assert(hitRec->hitInfo<=1);
BOOL state = selected;
if (invert) state = !sel[hitRec->hitInfo];
if (state) sel[hitRec->hitInfo] = 1;
else sel[hitRec->hitInfo] = 0;
if (!all) break;
hitRec = hitRec->Next();
}
NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
void AFRMod::ClearSelection(int selLevel)
{
//if (theHold.Holding()) theHold.Put(new SelRestore(this));
sel[0] = sel[1] = 0;
NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
void AFRMod::SelectAll(int selLevel)
{
//if (theHold.Holding()) theHold.Put(new SelRestore(this));
sel[0] = sel[1] = 1;
NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
void AFRMod::InvertSelection(int selLevel)
{
//if (theHold.Holding()) theHold.Put(new SelRestore(this));
sel[0] = !sel[0];
sel[1] = !sel[1];
NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
void AFRMod::ActivateSubobjSel(int level, XFormModes& modes)
{
switch (level) {
case 1: // Points
modes = XFormModes(moveMode,NULL,NULL,NULL,NULL,NULL);
break;
}
NotifyDependents(FOREVER,PART_DISPLAY,REFMSG_CHANGE);
}
BOOL AFRMod::AssignController(Animatable *control,int subAnim)
{
ReplaceReference(subAnim,(Control*)control);
NotifyDependents(FOREVER,PART_GEOM,REFMSG_CHANGE);
NotifyDependents(FOREVER,0,REFMSG_SUBANIM_STRUCTURE_CHANGED);
return TRUE;
}
int AFRMod::SubNumToRefNum(int subNum)
{
switch (subNum) {
case POINT1_REF: return POINT1_REF;
case POINT2_REF: return POINT2_REF;
}
return -1;
}
RefTargetHandle AFRMod::GetReference(int i)
{
switch (i) {
case PBLOCK_REF: return pblock;
case POINT1_REF: return p1;
case POINT2_REF: return p2;
default: return NULL;
}
}
void AFRMod::SetReference(int i, RefTargetHandle rtarg)
{
switch (i) {
case PBLOCK_REF: pblock = (IParamBlock*)rtarg; break;
case POINT1_REF: p1 = (Control*)rtarg; break;
case POINT2_REF: p2 = (Control*)rtarg; break;
}
}
TSTR AFRMod::SubAnimName(int i)
{
switch (i) {
case POINT1_REF: return GetString(IDS_RB_STARTPOINT); break;
case POINT2_REF: return GetString(IDS_RB_ENDPOINT); break;
default: return _T(""); break;
}
}
RefResult AFRMod::NotifyRefChanged(
Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message)
{
switch (message) {
case REFMSG_CHANGE:
if (editMod==this && pmapParam) pmapParam->Invalidate();
break;
case REFMSG_GET_PARAM_DIM: {
GetParamDim *gpd = (GetParamDim*)partID;
switch (gpd->index) {
case PB_FALLOFF: gpd->dim = stdWorldDim; break;
case PB_PINCH:
case PB_BUBBLE: gpd->dim = stdNormalizedDim; break;
}
return REF_STOP;
}
case REFMSG_GET_PARAM_NAME: {
GetParamName *gpn = (GetParamName*)partID;
switch (gpn->index) {
case PB_FALLOFF: gpn->name = GetString(IDS_AFR_FALLOFF); break;
case PB_PINCH: gpn->name = GetString(IDS_AFR_PINCH); break;
case PB_BUBBLE: gpn->name = GetString(IDS_AFR_BUBBLE); break;
}
return REF_STOP;
}
}
return REF_SUCCEED;
}
AFRDeformer::AFRDeformer(
ModContext &mc, float f, float p, float b,
Point3 pt1, Point3 pt2, Tab<Point3> *n)
{
Matrix3 tm, itm;
if (mc.tm) tm = *mc.tm;
else tm.IdentityMatrix();
itm = Inverse(tm);
falloff = f;
pinch = p;
bubble = b;
pt1 = pt1 * itm;
pt2 = pt2 * itm;
p1 = pt1;
p2 = pt2-p1;
normals = n;
}
Point3 AFRDeformer::Map(int i, Point3 p)
{
float dist = Length(p-p1), d;
if (dist>falloff) return p;
if (normals) {
d = DotProd(p2,(*normals)[i]);
if (d<0.0) return p;
}
float u = ((falloff - dist)/falloff);
float u2 = u*u, s = 1.0f-u;
return p + p2 * ((3*u*bubble*s + 3*u2*(1.0f-pinch))*s + u*u2);
}
@@ -0,0 +1,467 @@
/**********************************************************************
*<
FILE: bend.cpp
DESCRIPTION: Bend OSM
CREATED BY: Dan Silva & Rolf Berteig
HISTORY: created 30 Jauary, 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#include "simpmod.h"
#include "simpobj.h"
#define BIGFLOAT float(999999)
class BendMod : public SimpleMod {
public:
static IParamMap *pmapParam;
BendMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) { s= GetString(IDS_RB_BENDMOD); }
virtual Class_ID ClassID() { return Class_ID(BENDOSM_CLASS_ID,0);}
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams( IObjParam *ip,ULONG flags,Animatable *next);
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() { return GetString(IDS_RB_BEND2);}
IOResult Load(ILoad *iload);
// From simple mod
Deformer& GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat);
Interval GetValidity(TimeValue t);
ParamDimension *GetParameterDim(int pbIndex);
TSTR GetParameterName(int pbIndex);
BOOL GetModLimits(TimeValue t,float &zmin, float &zmax, int &axis);
void InvalidateUI() {if (pmapParam) pmapParam->Invalidate();}
};
class BendDeformer: public Deformer {
public:
Matrix3 tm,invtm, tmAbove, tmBelow;
Box3 bbox;
TimeValue time;
float r, from, to;
int doRegion;
BendDeformer();
BendDeformer(
TimeValue t, ModContext &mc,
float angle, float dir, int naxis,
float from, float to, int doRegion,
Matrix3& modmat, Matrix3& modinv);
void SetAxis(Matrix3 &tmAxis);
void CalcR(int axis, float angle);
Point3 Map(int i, Point3 p);
};
#define BENDWSM_CLASSID Class_ID(BENDOSM_CLASS_ID,1)
class BendWSM : public SimpleOSMToWSMObject {
public:
BendWSM() {}
BendWSM(BendMod *m) : SimpleOSMToWSMObject(m) {}
void DeleteThis() { delete this; }
SClass_ID SuperClassID() {return WSM_OBJECT_CLASS_ID;}
Class_ID ClassID() {return BENDWSM_CLASSID;}
TCHAR *GetObjectName() {return GetString(IDS_RB_BEND2);}
RefTargetHandle Clone(RemapDir& remap)
{return (new BendWSM((BendMod*)mod->Clone(remap)))->SimpleOSMToWSMClone(this,remap);}
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *BendMod::pmapParam = NULL;
class BendClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new BendMod; }
const TCHAR * ClassName() { return GetString(IDS_RB_BEND_CLASS); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(BENDOSM_CLASS_ID,0); }
const TCHAR* Category() { return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static BendClassDesc bendDesc;
extern ClassDesc* GetBendModDesc() { return &bendDesc; }
class BendWSMClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE)
{if (loading) return new BendWSM; else return new BendWSM(new BendMod);}
const TCHAR * ClassName() { return GetString(IDS_RB_BEND_CLASS); }
SClass_ID SuperClassID() { return WSM_OBJECT_CLASS_ID; }
Class_ID ClassID() { return BENDWSM_CLASSID; }
const TCHAR* Category() {return GetSpaceWarpCatString(SPACEWARP_CAT_MODBASED);}
};
static BendWSMClassDesc bendWSMDesc;
extern ClassDesc* GetBendWSMDesc() { return &bendWSMDesc; }
//--- Parameter map/block descriptors -------------------------------
#define PB_ANGLE 0
#define PB_DIR 1
#define PB_AXIS 2
#define PB_DOREGION 3
#define PB_FROM 4
#define PB_TO 5
//
//
// Parameters
static int axisIDs[] = {IDC_X,IDC_Y,IDC_Z};
static ParamUIDesc descParam[] = {
// Angle
ParamUIDesc(
PB_ANGLE,
EDITTYPE_FLOAT,
IDC_ANGLE,IDC_ANGLESPINNER,
-BIGFLOAT,BIGFLOAT,
0.5f),
// Direction
ParamUIDesc(
PB_DIR,
EDITTYPE_FLOAT,
IDC_DIR,IDC_DIRSPINNER,
-BIGFLOAT,BIGFLOAT,
0.5f),
// Axis
ParamUIDesc(PB_AXIS,TYPE_RADIO,axisIDs,3),
// Affect region
ParamUIDesc(PB_DOREGION,TYPE_SINGLECHEKBOX,IDC_BEND_AFFECTREGION),
// From
ParamUIDesc(
PB_FROM,
EDITTYPE_UNIVERSE,
IDC_BEND_FROM,IDC_BEND_FROMSPIN,
-BIGFLOAT,0.0f,
SPIN_AUTOSCALE),
// To
ParamUIDesc(
PB_TO,
EDITTYPE_UNIVERSE,
IDC_BEND_TO,IDC_BEND_TOSPIN,
0.0f,BIGFLOAT,
SPIN_AUTOSCALE),
};
#define PARAMDESC_LENGH 6
static ParamBlockDescID descVer0[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_INT, NULL, FALSE, 2 } };
static ParamBlockDescID descVer1[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_INT, NULL, FALSE, 2 },
{ TYPE_INT, NULL, FALSE, 3 },
{ TYPE_FLOAT, NULL, TRUE, 4 },
{ TYPE_FLOAT, NULL, TRUE, 5 } };
#define PBLOCK_LENGTH 6
// Array of old versions
static ParamVersionDesc versions[] = {
ParamVersionDesc(descVer0,3,0)
};
#define NUM_OLDVERSIONS 1
// Current version
#define CURRENT_VERSION 1
static ParamVersionDesc curVersion(descVer1,PBLOCK_LENGTH,CURRENT_VERSION);
//--- BendDlgProc -------------------------------
class BendDlgProc : public ParamMapUserDlgProc {
public:
BOOL DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
void DeleteThis() {}
};
static BendDlgProc theBendProc;
BOOL BendDlgProc::DlgProc(
TimeValue t,IParamMap *map,
HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg) {
case CC_SPINNER_CHANGE:
switch (LOWORD(wParam)) {
case IDC_BEND_FROMSPIN: {
float from, to;
map->GetParamBlock()->GetValue(PB_FROM,t,from,FOREVER);
map->GetParamBlock()->GetValue(PB_TO,t,to,FOREVER);
if (from>to) {
map->GetParamBlock()->SetValue(PB_TO,t,from);
map->Invalidate();
}
break;
}
case IDC_BEND_TOSPIN: {
float from, to;
map->GetParamBlock()->GetValue(PB_FROM,t,from,FOREVER);
map->GetParamBlock()->GetValue(PB_TO,t,to,FOREVER);
if (from>to) {
map->GetParamBlock()->SetValue(PB_FROM,t,to);
map->Invalidate();
}
break;
}
}
break;
}
return FALSE;
}
//--- Bend methods -------------------------------
BendMod::BendMod() : SimpleMod()
{
MakeRefByID(FOREVER, SIMPMOD_PBLOCKREF,
CreateParameterBlock(descVer1, PBLOCK_LENGTH, CURRENT_VERSION));
pblock->SetValue(PB_AXIS, TimeValue(0), 2/*Z*/);
}
IOResult BendMod::Load(ILoad *iload)
{
Modifier::Load(iload);
iload->RegisterPostLoadCallback(
new ParamBlockPLCB(versions,NUM_OLDVERSIONS,&curVersion,this,SIMPMOD_PBLOCKREF));
return IO_OK;
}
void BendMod::BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev )
{
SimpleMod::BeginEditParams(ip,flags,prev);
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_BENDPARAM),
GetString(IDS_RB_PARAMETERS),
0);
pmapParam->SetUserDlgProc(&theBendProc);
}
void BendMod::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
{
SimpleMod::EndEditParams(ip,flags,next);
DestroyCPParamMap(pmapParam);
}
Interval BendMod::GetValidity(TimeValue t)
{
float f;
Interval valid = FOREVER;
pblock->GetValue(PB_ANGLE,t,f,valid);
pblock->GetValue(PB_DIR,t,f,valid);
pblock->GetValue(PB_FROM,t,f,valid);
pblock->GetValue(PB_TO,t,f,valid);
return valid;
}
BOOL BendMod::GetModLimits(TimeValue t,float &zmin, float &zmax, int &axis)
{
int limit;
pblock->GetValue(PB_DOREGION,t,limit,FOREVER);
pblock->GetValue(PB_FROM,t,zmin,FOREVER);
pblock->GetValue(PB_TO,t,zmax,FOREVER);
pblock->GetValue(PB_AXIS,t,axis,FOREVER);
return limit?TRUE:FALSE;
}
RefTargetHandle BendMod::Clone(RemapDir& remap) {
BendMod* newmod = new BendMod();
newmod->ReplaceReference(SIMPMOD_PBLOCKREF,pblock->Clone(remap));
newmod->SimpleModClone(this);
return(newmod);
}
BendDeformer::BendDeformer()
{
tm.IdentityMatrix();
time = 0;
}
void BendDeformer::SetAxis(Matrix3 &tmAxis)
{
Matrix3 itm = Inverse(tmAxis);
tm = tm*tmAxis;
invtm = itm*invtm;
}
void BendDeformer::CalcR(int axis, float angle)
{
float len = float(0);
if (!doRegion) {
switch (axis) {
case 0: len = bbox.pmax.x - bbox.pmin.x; break;
case 1: len = bbox.pmax.y - bbox.pmin.y; break;
case 2: len = bbox.pmax.z - bbox.pmin.z; break;
}
} else {
len = to-from;
}
// Skip the singularity
if (fabs(angle) <0.0001) {
r = float(0);
} else {
r = len/angle;
}
}
Point3 BendDeformer::Map(int i, Point3 p)
{
float x, y, c, s, yr;
if (r==0 && !doRegion) return p;
p = p * tm;
if (doRegion) {
if (p.z<from) {
return tmBelow * p * invtm;
} else
if (p.z>to) {
return tmAbove * p * invtm;
}
}
if (r==0) return p * invtm;
x = p.x;
y = p.z;
yr = y/r;
c = float(cos(PI-yr));
s = float(sin(PI-yr));
p.x = r*c + r - x*c;
p.z = r*s - x*s;
p = p * invtm;
return p;
}
BendDeformer::BendDeformer(
TimeValue t, ModContext &mc,
float angle, float dir, int naxis,
float from, float to, int doRegion,
Matrix3& modmat, Matrix3& modinv)
{
this->doRegion = doRegion;
this->from = from;
this->to = to;
Matrix3 mat;
Interval valid;
time = t;
tm = modmat;
invtm = modinv;
mat.IdentityMatrix();
switch (naxis) {
case 0: mat.RotateY( -HALFPI ); break; //X
case 1: mat.RotateX( HALFPI ); break; //Y
case 2: break; //Z
}
mat.RotateZ(DegToRad(dir));
SetAxis(mat);
assert (mc.box);
bbox = *mc.box;
CalcR(naxis,DegToRad(angle));
// Turn this off for a sec.
this->doRegion = FALSE;
float len = to-from;
float rat1, rat2;
if (len==0.0f) {
rat1 = rat2 = 1.0f;
} else {
rat1 = to/len;
rat2 = from/len;
}
Point3 pt;
tmAbove.IdentityMatrix();
tmAbove.Translate(Point3(0.0f,0.0f,-to));
tmAbove.RotateY(DegToRad(angle * rat1));
tmAbove.Translate(Point3(0.0f,0.0f,to));
pt = Point3(0.0f,0.0f,to);
tmAbove.Translate((Map(0,pt*invtm)*tm)-pt);
tmBelow.IdentityMatrix();
tmBelow.Translate(Point3(0.0f,0.0f,-from));
tmBelow.RotateY(DegToRad(angle * rat2));
tmBelow.Translate(Point3(0.0f,0.0f,from));
pt = Point3(0.0f,0.0f,from);
tmBelow.Translate((Map(0,pt*invtm)*tm)-pt);
this->doRegion = doRegion;
}
Deformer& BendMod::GetDeformer(
TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
{
float angle, dir, from, to;
int axis;
int doRegion;
pblock->GetValue(PB_ANGLE,t,angle,FOREVER);
pblock->GetValue(PB_DIR,t,dir,FOREVER);
pblock->GetValue(PB_AXIS,t,axis,FOREVER);
pblock->GetValue(PB_FROM,t,from,FOREVER);
pblock->GetValue(PB_TO,t,to,FOREVER);
pblock->GetValue(PB_DOREGION,t,doRegion,FOREVER);
static BendDeformer deformer;
deformer = BendDeformer(t,mc,angle,dir,axis,from,to,doRegion,mat,invmat);
return deformer;
}
ParamDimension *BendMod::GetParameterDim(int pbIndex)
{
switch (pbIndex) {
case PB_ANGLE: return defaultDim; // Note: doesn't use angleDim because the bend has been storing the angle in degrees not radians. Changing this would invalidate old files.
case PB_DIR: return defaultDim;
case PB_FROM: return stdWorldDim;
case PB_TO: return stdWorldDim;
default: return defaultDim;
}
}
TSTR BendMod::GetParameterName(int pbIndex)
{
switch (pbIndex) {
case PB_ANGLE: return GetString(IDS_RB_ANGLE);
case PB_DIR: return GetString(IDS_RB_DIRECTION);
case PB_FROM: return GetString(IDS_RB_FROM);
case PB_TO: return GetString(IDS_RB_TO);
default: return _T("");
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,310 @@
/**********************************************************************
*<
FILE: clstnode.cpp
DESCRIPTION: Vertex cluster animating modifier that uses nodes
CREATED BY: Rolf Berteig
HISTORY: created 27 October, 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
class ClustNodeMod : public Modifier {
public:
INode *node;
static IObjParam *ip;
static HWND hParams;
Matrix3 tm, invtm;
ClustNodeMod();
~ClustNodeMod();
// From Animatable
void DeleteThis() {delete this;}
void GetClassName(TSTR& s) { s= GetString(IDS_RB_CLUSTNODEMOD); }
virtual Class_ID ClassID() { return Class_ID(CLUSTNODEOSM_CLASS_ID,0);}
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip,ULONG flags,Animatable *next);
TCHAR *GetObjectName() {return GetString(IDS_RB_NODEXFORM);}
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
ChannelMask ChannelsUsed() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_SUBSEL_TYPE;}
ChannelMask ChannelsChanged() {return PART_GEOM;}
Class_ID InputType() {return defObjectClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t);
int NumRefs() {return 1;}
RefTargetHandle GetReference(int i) {return node;}
void SetReference(int i, RefTargetHandle rtarg) {node=(INode*)rtarg;}
IOResult Load(ILoad *iload);
IOResult Save(ISave *isave);
RefTargetHandle Clone(RemapDir& remap = NoRemap());
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
};
//--- ClassDescriptor and class vars ---------------------------------
IObjParam* ClustNodeMod::ip = NULL;
HWND ClustNodeMod::hParams = NULL;
class ClustNodeClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) {return new ClustNodeMod;}
const TCHAR * ClassName() {return GetString(IDS_RB_NODEXFORM_CLASS);}
SClass_ID SuperClassID() {return OSM_CLASS_ID;}
Class_ID ClassID() {return Class_ID(CLUSTNODEOSM_CLASS_ID,0); }
const TCHAR* Category() {return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static ClustNodeClassDesc clustNodeDesc;
extern ClassDesc* GetClustNodeModDesc() {return &clustNodeDesc;}
//--- CustMod dlg proc ------------------------------
class PickControlNode :
public PickModeCallback,
public PickNodeCallback {
public:
ClustNodeMod *mod;
PickControlNode() {mod=NULL;}
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 Filter(INode *node);
PickNodeCallback *GetFilter() {return this;}
BOOL RightClick(IObjParam *ip,ViewExp *vpt) {return TRUE;}
};
static PickControlNode thePickMode;
BOOL PickControlNode::Filter(INode *node)
{
node->BeginDependencyTest();
mod->NotifyDependents(FOREVER,0,REFMSG_TEST_DEPENDENCY);
if (node->EndDependencyTest()) {
return FALSE;
} else {
return TRUE;
}
}
BOOL PickControlNode::HitTest(
IObjParam *ip,HWND hWnd,ViewExp *vpt,IPoint2 m,int flags)
{
if (ip->PickNode(hWnd,m,this)) {
return TRUE;
} else {
return FALSE;
}
}
BOOL PickControlNode::Pick(IObjParam *ip,ViewExp *vpt)
{
INode *node = vpt->GetClosestHit();
if (node) {
Matrix3 ourTM,ntm = node->GetObjectTM(ip->GetTime());
ModContextList mcList;
INodeTab nodes;
ip->GetModContexts(mcList,nodes);
assert(nodes.Count());
ourTM = nodes[0]->GetObjectTM(ip->GetTime());
mod->tm = ourTM * Inverse(ntm);
mod->invtm = Inverse(ourTM);
mod->ReplaceReference(0,node);
mod->NotifyDependents(FOREVER,0,REFMSG_CHANGE);
SetWindowText(GetDlgItem(mod->hParams,IDC_CLUST_NODENAME),
mod->node->GetName());
nodes.DisposeTemporary();
}
return TRUE;
}
void PickControlNode::EnterMode(IObjParam *ip)
{
ICustButton *iBut = GetICustButton(GetDlgItem(mod->hParams,IDC_CLUST_PICKNODE));
if (iBut) iBut->SetCheck(TRUE);
ReleaseICustButton(iBut);
}
void PickControlNode::ExitMode(IObjParam *ip)
{
ICustButton *iBut = GetICustButton(GetDlgItem(mod->hParams,IDC_CLUST_PICKNODE));
if (iBut) iBut->SetCheck(FALSE);
ReleaseICustButton(iBut);
}
static BOOL CALLBACK ClustParamDlgProc(
HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
ClustNodeMod *mod = (ClustNodeMod*)GetWindowLong(hWnd,GWL_USERDATA);
switch (msg) {
case WM_INITDIALOG: {
SetWindowLong(hWnd,GWL_USERDATA,lParam);
mod = (ClustNodeMod*)lParam;
ICustButton *iBut = GetICustButton(GetDlgItem(hWnd,IDC_CLUST_PICKNODE));
iBut->SetType(CBT_CHECK);
iBut->SetHighlightColor(GREEN_WASH);
ReleaseICustButton(iBut);
if (mod->node) {
SetWindowText(GetDlgItem(hWnd,IDC_CLUST_NODENAME),
mod->node->GetName());
} else {
SetWindowText(GetDlgItem(hWnd,IDC_CLUST_NODENAME),
GetString(IDS_RB_NONE));
}
break;
}
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_CLUST_PICKNODE:
thePickMode.mod = mod;
mod->ip->SetPickMode(&thePickMode);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
//--- ClustMod methods -------------------------------
ClustNodeMod::ClustNodeMod()
{
node = NULL;
tm = Matrix3(1);
invtm = Matrix3(1);
}
ClustNodeMod::~ClustNodeMod()
{
DeleteAllRefsFromMe();
}
#define CLUSTNODE_TM_CHUNK 0x0100
#define CLUSTNODE_INVTM_CHUNK 0x0110
IOResult ClustNodeMod::Load(ILoad *iload)
{
Modifier::Load(iload);
IOResult res = IO_OK;
while (IO_OK==(res=iload->OpenChunk())) {
switch (iload->CurChunkID()) {
case CLUSTNODE_TM_CHUNK:
tm.Load(iload);
break;
case CLUSTNODE_INVTM_CHUNK:
invtm.Load(iload);
break;
}
iload->CloseChunk();
if (res!=IO_OK) return res;
}
return IO_OK;
}
IOResult ClustNodeMod::Save(ISave *isave)
{
Modifier::Save(isave);
isave->BeginChunk(CLUSTNODE_TM_CHUNK);
tm.Save(isave);
isave->EndChunk();
isave->BeginChunk(CLUSTNODE_INVTM_CHUNK);
invtm.Save(isave);
isave->EndChunk();
return IO_OK;
}
void ClustNodeMod::BeginEditParams(
IObjParam *ip, ULONG flags,Animatable *prev)
{
this->ip = ip;
hParams = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_CLUSTNODEPARAM),
ClustParamDlgProc,
GetString(IDS_RB_PARAMETERS),
(LPARAM)this);
}
void ClustNodeMod::EndEditParams(
IObjParam *ip,ULONG flags,Animatable *next)
{
ip->ClearPickMode();
this->ip = NULL;
ip->DeleteRollupPage(hParams);
}
class ClustNodeDeformer: public Deformer {
public:
Matrix3 tm,invtm;
ClustNodeDeformer(Matrix3 m,Matrix3 mi) {tm=m;invtm=mi;}
Point3 Map(int i, Point3 p) {return (p*tm)*invtm;}
};
void ClustNodeMod::ModifyObject(
TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
if (this->node) {
Interval valid = FOREVER;
Matrix3 ntm = this->node->GetNodeTM(t,&valid);
ClustNodeDeformer deformer(tm*ntm,invtm);
os->obj->Deform(&deformer, TRUE);
os->obj->UpdateValidity(GEOM_CHAN_NUM,valid);
}
}
Interval ClustNodeMod::LocalValidity(TimeValue t)
{
Interval valid = FOREVER;
if (node) {
node->GetNodeTM(t,&valid);
}
return valid;
}
RefTargetHandle ClustNodeMod::Clone(RemapDir& remap)
{
ClustNodeMod *newmod = new ClustNodeMod;
newmod->ReplaceReference(0,node);
newmod->tm = tm;
newmod->invtm = invtm;
return newmod;
}
RefResult ClustNodeMod::NotifyRefChanged(
Interval changeInt,
RefTargetHandle hTarget,
PartID& partID,
RefMessage message)
{
switch (message) {
case REFMSG_TARGET_DELETED:
if (hTarget==node) {
node = NULL;
}
break;
}
return REF_SUCCEED;
}
@@ -0,0 +1,340 @@
/**********************************************************************
*<
FILE: clustmod.cpp
DESCRIPTION: Vertex cluster animating modifier
CREATED BY: Rolf Berteig
HISTORY: created 24 August, 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "simpmod.h"
#include "buildver.h"
class ClustMod : public SimpleMod {
private:
int selLevel;
public:
ClustMod();
void DeleteThis() {delete this;}
void GetClassName(TSTR& s) { s= GetString(IDS_RB_XFORM_CLASS); }
Class_ID ClassID() { return Class_ID(CLUSTOSM_CLASS_ID,0);}
RefTargetHandle Clone(RemapDir& remap);
TCHAR *GetObjectName() { return GetString(IDS_RB_XFORM); }
Deformer& GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat);
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node);
int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc);
int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags, ModContext *mc);
void GetWorldBoundBox(TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc);
void GetSubObjectCenters(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void GetSubObjectTMs(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void Move(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin);
void ActivateSubobjSel(int level, XFormModes& modes);
};
class ClustDeformer: public Deformer {
public:
Matrix3 tm;
ClustDeformer();
ClustDeformer(Matrix3& modmat);
Point3 Map(int i, Point3 p);
};
class ClustClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE) {return new ClustMod;}
const TCHAR * ClassName() { return GetString(IDS_RB_XFORM_CLASS); }
SClass_ID SuperClassID() {return OSM_CLASS_ID; }
Class_ID ClassID() {return Class_ID(CLUSTOSM_CLASS_ID,0); }
const TCHAR* Category() {return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static ClustClassDesc clustDesc;
extern ClassDesc* GetClustModDesc() { return &clustDesc; }
/*--------------------------------------------------------------------*/
RefTargetHandle ClustMod::Clone(RemapDir& remap)
{
ClustMod* newmod = new ClustMod();
newmod->SimpleModClone(this);
return(newmod);
}
ClustDeformer::ClustDeformer()
{
tm.IdentityMatrix();
}
Point3 ClustDeformer::Map(int i, Point3 p)
{
p = p * tm;
return p;
}
ClustDeformer::ClustDeformer(Matrix3& modmat)
{
tm = modmat;
}
ClustMod::ClustMod()
{
// We'll use A_WORK4 to indicate that this mod was just created.
// The first time we enter BeginEditParams() we'll go directly into
// sub object selection
//SetAFlag(A_WORK4);
selLevel = 1;
}
Deformer& ClustMod::GetDeformer(
TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
{
static ClustDeformer deformer;
assert(0);
return deformer;
}
void ClustMod::BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev)
{
SimpleMod::BeginEditParams(ip,flags,prev);
//if (TestAFlag(A_WORK4)) ip->SetSubObjectLevel(1);
//ClearAFlag(A_WORK4);
if (selLevel) ip->SetSubObjectLevel(1);
}
void ClustMod::ActivateSubobjSel(int level, XFormModes& modes)
{
selLevel = level;
SimpleMod::ActivateSubobjSel(level,modes);
}
#define DEFORMER_TM (ptm * ctm)
static Matrix3 CompTM(
Matrix3 &ptm, Matrix3 &ctm, Matrix3 *mctm, int i)
{
if (mctm) {
if (i) return ptm * ctm * Inverse(*mctm);
else return *mctm * ptm * ctm * Inverse(*mctm);
} else {
return ptm * ctm;
}
}
void ClustMod::ModifyObject(
TimeValue t, ModContext &mc, ObjectState * os, INode *node)
{
Interval valid = FOREVER;
Matrix3 ptm(1), ctm(1);
if (posControl) posControl->GetValue(t,&ptm,valid,CTRL_RELATIVE);
if (tmControl) tmControl->GetValue(t,&ctm,valid,CTRL_RELATIVE);
//Matrix3 tm = DEFORMER_TM;
Matrix3 tm = CompTM(ptm,ctm,mc.tm,0);
ClustDeformer deformer(tm);
os->obj->Deform(&deformer, TRUE);
os->obj->UpdateValidity(GEOM_CHAN_NUM,valid);
}
int ClustMod::HitTest(
TimeValue t, INode* inode, int type, int crossing,
int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc)
{
int savedLimits;
Matrix3 obtm = inode->GetObjectTM(t);
GraphicsWindow *gw = vpt->getGW();
HitRegion hr;
MakeHitRegion(hr,type, crossing,4,p);
gw->setHitRegion(&hr);
gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM);
gw->clearHitCode();
gw->setTransform(obtm);
Matrix3 ptm(1), ctm(1);
if (posControl) posControl->GetValue(t,&ptm,FOREVER,CTRL_RELATIVE);
if (tmControl) tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE);
if (ip && ip->GetSubObjectLevel() == 1) {
//Matrix3 tm = DEFORMER_TM;
Matrix3 tm = CompTM(ptm,ctm,mc->tm,1);
ClustDeformer deformer(tm);
if (mc->box->pmin==mc->box->pmax) {
Point3 pt = mc->box->pmin * tm;
gw->marker(&pt,ASTERISK_MRKR);
} else {
DoModifiedBox(*mc->box,deformer,DrawLineProc(gw));
}
}
if (ip && (ip->GetSubObjectLevel() == 1 ||
ip->GetSubObjectLevel() == 2)) {
//obtm = ctm * obtm;
if (mc->tm) obtm = ctm * Inverse(*mc->tm) * obtm;
else obtm = ctm * obtm;
gw->setTransform(obtm);
DrawCenterMark(DrawLineProc(gw),*mc->box);
}
gw->setRndLimits(savedLimits);
if (gw->checkHitCode()) {
vpt->LogHit(inode, mc, gw->getHitDistance(), 0, NULL);
return 1;
}
return 0;
}
int ClustMod::Display(
TimeValue t, INode* inode, ViewExp *vpt,
int flags, ModContext *mc)
{
Matrix3 obtm = inode->GetObjectTM(t);
GraphicsWindow *gw = vpt->getGW();
gw->setTransform(obtm);
Matrix3 ptm(1), ctm(1);
if (posControl) posControl->GetValue(t,&ptm,FOREVER,CTRL_RELATIVE);
if (tmControl) tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE);
//Matrix3 tm = DEFORMER_TM;
Matrix3 tm = CompTM(ptm,ctm,mc->tm,1);
ClustDeformer deformer(tm);
if (ip && ip->GetSubObjectLevel() == 1) {
//gw->setColor( LINE_COLOR, (float)1.0, (float)1.0, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
} else {
//gw->setColor( LINE_COLOR, (float).85, (float).5, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS));
}
if (mc->box->pmin==mc->box->pmax) {
Point3 pt = mc->box->pmin * tm;
gw->marker(&pt,ASTERISK_MRKR);
} else {
DoModifiedBox(*mc->box,deformer,DrawLineProc(gw));
}
//obtm = ctm * obtm;
if (mc->tm) obtm = ctm * Inverse(*mc->tm) * obtm;
else obtm = ctm * obtm;
gw->setTransform(obtm);
if ( ip && (ip->GetSubObjectLevel() == 1 ||
ip->GetSubObjectLevel() == 2) ) {
//gw->setColor( LINE_COLOR, (float)1.0, (float)1.0, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
} else {
//gw->setColor( LINE_COLOR, (float).85, (float).5, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS));
}
DrawCenterMark(DrawLineProc(gw),*mc->box);
return 0;
}
void ClustMod::GetWorldBoundBox(
TimeValue t,INode* inode, ViewExp *vpt,
Box3& box, ModContext *mc)
{
Matrix3 obtm = inode->GetObjectTM(t);
GraphicsWindow *gw = vpt->getGW();
Matrix3 ptm(1), ctm(1);
if (posControl) posControl->GetValue(t,&ptm,FOREVER,CTRL_RELATIVE);
if (tmControl) tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE);
//Matrix3 tm = DEFORMER_TM;
Matrix3 tm = CompTM(ptm,ctm,mc->tm,1);
ClustDeformer deformer(tm);
BoxLineProc bp1(&obtm);
DoModifiedBox(*mc->box, deformer, bp1);
box = bp1.Box();
//obtm = ctm * obtm;
if (mc->tm) obtm = ctm * Inverse(*mc->tm) * obtm;
else obtm = ctm * obtm;
BoxLineProc bp2(&obtm);
DrawCenterMark(bp2,*mc->box);
box += bp2.Box();
}
void ClustMod::GetSubObjectCenters(
SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc)
{
Matrix3 obtm = node->GetObjectTM(t);
Matrix3 ptm(1), ctm(1);
if (posControl) posControl->GetValue(t,&ptm,FOREVER,CTRL_RELATIVE);
if (tmControl) tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE);
if (cb->Type()==SO_CENTER_PIVOT) {
//Matrix3 mat = ctm * obtm;
Matrix3 mat;
if (mc->tm) mat = ctm * Inverse(*mc->tm) * obtm;
else mat = ctm * obtm;
cb->Center(mat.GetTrans(),0);
} else {
//Matrix3 tm = DEFORMER_TM;
Matrix3 tm = CompTM(ptm,ctm,mc->tm,1);
ClustDeformer deformer(tm);
BoxLineProc bp1(&obtm);
DoModifiedBox(*mc->box, deformer, bp1);
cb->Center(bp1.Box().Center(),0);
}
}
void ClustMod::GetSubObjectTMs(
SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc)
{
Matrix3 obtm = node->GetObjectTM(t);
Matrix3 ptm(1), ctm(1);
if (posControl) posControl->GetValue(t,&ptm,FOREVER,CTRL_RELATIVE);
if (tmControl) tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE);
//Matrix3 tm = DEFORMER_TM * obtm;
Matrix3 tm = CompTM(ptm,ctm,mc->tm,1) * obtm;
cb->TM(tm,0);
}
void ClustMod::Move(
TimeValue t, Matrix3& partm, Matrix3& tmAxis,
Point3& val, BOOL localOrigin)
{
#ifdef DESIGN_VER
t=0;
#endif
if (tmControl==NULL) {
MakeRefByID(FOREVER,0,NewDefaultMatrix3Controller());
NotifyDependents(FOREVER,0,REFMSG_CONTROLREF_CHANGE);
}
if (ip && ip->GetSubObjectLevel()==1) {
SetXFormPacket pckt(val,partm,tmAxis);
tmControl->SetValue(t,&pckt,TRUE,CTRL_RELATIVE);
} else {
if (posControl==NULL) {
MakeRefByID(FOREVER,1,NewDefaultPositionController());
NotifyDependents(FOREVER,0,REFMSG_CONTROLREF_CHANGE);
}
Matrix3 ptm = partm;
Interval valid;
if (tmControl)
tmControl->GetValue(t,&ptm,valid,CTRL_RELATIVE);
posControl->SetValue(t,-VectorTransform(tmAxis*Inverse(ptm),val),TRUE,CTRL_RELATIVE);
SetXFormPacket pckt(val,partm,tmAxis);
tmControl->SetValue(t,&pckt,TRUE,CTRL_RELATIVE);
}
}
@@ -0,0 +1,444 @@
/**********************************************************************
*<
FILE: deflect.cpp
DESCRIPTION: A simple deflector object for particles
CREATED BY: Rolf Berteig
HISTORY: 10-31-95
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#include "simpmod.h"
#include "simpobj.h"
#include "texutil.h"
class DeflectObject : public SimpleWSMObject {
public:
static IParamMap *pmapParam;
static IObjParam *ip;
static HWND hSot;
DeflectObject();
// From Animatable
void DeleteThis() {delete this;}
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next);
Class_ID ClassID() {return Class_ID(DEFLECTOBJECT_CLASS_ID,0);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_DEFLECTOR);}
// from object
CreateMouseCallBack* GetCreateMouseCallBack();
// From SimpleWSMObject
void InvalidateUI();
void BuildMesh(TimeValue t);
ParamDimension *GetParameterDim(int pbIndex);
TSTR GetParameterName(int pbIndex);
// From WSMObject
Modifier *CreateWSMMod(INode *node);
};
//--- ClassDescriptor and class vars ---------------------------------
IObjParam *DeflectObject::ip = NULL;
IParamMap *DeflectObject::pmapParam = NULL;
HWND DeflectObject::hSot = NULL;
class DeflectorClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE) { return new DeflectObject;}
const TCHAR * ClassName() {return GetString(IDS_RB_DEFLECTOR_CLASS);}
SClass_ID SuperClassID() {return WSM_OBJECT_CLASS_ID; }
Class_ID ClassID() {return Class_ID(DEFLECTOBJECT_CLASS_ID,0);}
const TCHAR* Category() {return GetSpaceWarpCatString(SPACEWARP_CAT_PARTICLE);}
};
static DeflectorClassDesc deflectDesc;
ClassDesc* GetDeflectObjDesc() {return &deflectDesc;}
//--- DeflectMod -----------------------------------------------------
class DeflectorField : public CollisionObject {
public:
DeflectObject *obj;
INode *node;
Matrix3 tm, invtm;
Interval tmValid;
BOOL CheckCollision(TimeValue t,Point3 &pos, Point3 &vel, float dt, int index);
};
class DeflectMod : public SimpleWSMMod {
public:
DeflectorField deflect;
DeflectMod() {}
DeflectMod(INode *node,DeflectObject *obj);
// From Animatable
void GetClassName(TSTR& s) {s= GetString(IDS_RB_DEFLECTMOD);}
SClass_ID SuperClassID() {return WSM_CLASS_ID;}
void DeleteThis() {delete this;}
Class_ID ClassID() { return Class_ID(DEFLECTMOD_CLASS_ID,0);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_DEFLECTORBINDING);}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
// From SimpleWSMMod
Interval GetValidity(TimeValue t);
Deformer& GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat);
};
//--- ClassDescriptor and class vars ---------------------------------
class DeflectorModClassDesc:public ClassDesc {
public:
int IsPublic() {return 0;}
void * Create(BOOL loading = FALSE) { return new DeflectMod;}
const TCHAR * ClassName() {return GetString(IDS_RB_DEFLECTMOD);}
SClass_ID SuperClassID() {return WSM_CLASS_ID; }
Class_ID ClassID() {return Class_ID(DEFLECTMOD_CLASS_ID,0);}
const TCHAR* Category() {return _T("");}
};
static DeflectorModClassDesc deflectModDesc;
ClassDesc* GetDeflectModDesc() {return &deflectModDesc;}
//--- DeflectObject Parameter map/block descriptors ------------------
#define PB_BOUNCE 0
#define PB_WIDTH 1
#define PB_HEIGHT 2
static ParamUIDesc descParam[] = {
// Bounce
ParamUIDesc(
PB_BOUNCE,
EDITTYPE_FLOAT,
IDC_DEFLECT_BOUNCE,IDC_DEFLECT_BOUNCESPIN,
0.0f, 9999999.0f,
0.01f),
// Width
ParamUIDesc(
PB_WIDTH,
EDITTYPE_FLOAT,
IDC_DEFLECT_WIDTH,IDC_DEFLECT_WIDTHSPIN,
0.0f, 9999999.0f,
SPIN_AUTOSCALE),
// height
ParamUIDesc(
PB_HEIGHT,
EDITTYPE_FLOAT,
IDC_DEFLECT_HEIGHT,IDC_DEFLECT_HEIGHTSPIN,
0.0f, 9999999.0f,
SPIN_AUTOSCALE)
};
#define PARAMDESC_LENGTH 3
ParamBlockDescID descVer0[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_FLOAT, NULL, TRUE, 2 }};
#define PBLOCK_LENGTH 3
#define CURRENT_VERSION 0
//--- Deflect object methods -----------------------------------------
DeflectObject::DeflectObject()
{
MakeRefByID(FOREVER, 0,
CreateParameterBlock(descVer0, PBLOCK_LENGTH, CURRENT_VERSION));
assert(pblock);
pblock->SetValue(PB_BOUNCE,0,1.0f);
}
Modifier *DeflectObject::CreateWSMMod(INode *node)
{
return new DeflectMod(node,this);
}
RefTargetHandle DeflectObject::Clone(RemapDir& remap)
{
DeflectObject* newob = new DeflectObject();
newob->ReplaceReference(0,pblock->Clone(remap));
return newob;
}
void DeflectObject::BeginEditParams(
IObjParam *ip,ULONG flags,Animatable *prev)
{
SimpleWSMObject::BeginEditParams(ip,flags,prev);
this->ip = ip;
if (pmapParam) {
// Left over
pmapParam->SetParamBlock(pblock);
} else {
hSot = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_WINDRAIN_SOT),
DefaultSOTProc,
GetString(IDS_RB_SOT),
(LPARAM)ip,APPENDROLL_CLOSED);
// Gotta make a new one.
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGTH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_DEFLECTORPARAM),
GetString(IDS_RB_PARAMETERS),
0);
}
}
void DeflectObject::EndEditParams(
IObjParam *ip, ULONG flags,Animatable *next)
{
SimpleWSMObject::EndEditParams(ip,flags,next);
this->ip = NULL;
if (flags&END_EDIT_REMOVEUI ) {
DestroyCPParamMap(pmapParam);
ip->DeleteRollupPage(hSot);
pmapParam = NULL;
}
}
void DeflectObject::BuildMesh(TimeValue t)
{
float width, height;
ivalid = FOREVER;
pblock->GetValue(PB_WIDTH,t,width,ivalid);
pblock->GetValue(PB_HEIGHT,t,height,ivalid);
width *= 0.5f;
height *= 0.5f;
mesh.setNumVerts(4);
mesh.setNumFaces(2);
mesh.setVert(0, Point3(-width,-height, 0.0f));
mesh.setVert(1, Point3( width,-height, 0.0f));
mesh.setVert(2, Point3( width, height, 0.0f));
mesh.setVert(3, Point3(-width, height, 0.0f));
mesh.faces[0].setEdgeVisFlags(1,0,1);
mesh.faces[0].setSmGroup(1);
mesh.faces[0].setVerts(0,1,3);
mesh.faces[1].setEdgeVisFlags(1,1,0);
mesh.faces[1].setSmGroup(1);
mesh.faces[1].setVerts(1,2,3);
mesh.InvalidateGeomCache();
}
class DeflectObjCreateCallback : public CreateMouseCallBack {
public:
DeflectObject *ob;
Point3 p0, p1;
IPoint2 sp0, sp1;
int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat);
};
int DeflectObjCreateCallback::proc(
ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat)
{
if (msg==MOUSE_POINT||msg==MOUSE_MOVE) {
switch(point) {
case 0:
sp0 = m;
p0 = vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE);
mat.SetTrans(p0);
ob->pblock->SetValue(PB_WIDTH,0,0.01f);
ob->pblock->SetValue(PB_HEIGHT,0,0.01f);
ob->pmapParam->Invalidate();
break;
case 1: {
mat.IdentityMatrix();
sp1 = m;
p1 = vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE);
Point3 center = (p0+p1)/float(2);
mat.SetTrans(center);
ob->pblock->SetValue(PB_WIDTH,0,(float)fabs(p1.x-p0.x));
ob->pblock->SetValue(PB_HEIGHT,0,(float)fabs(p1.y-p0.y));
ob->pmapParam->Invalidate();
if (msg==MOUSE_POINT) {
if (Length(m-sp0)<3) {
return CREATE_ABORT;
} else {
return CREATE_STOP;
}
}
break;
}
}
} else {
if (msg == MOUSE_ABORT)
return CREATE_ABORT;
}
return TRUE;
}
static DeflectObjCreateCallback deflectCreateCB;
CreateMouseCallBack* DeflectObject::GetCreateMouseCallBack()
{
deflectCreateCB.ob = this;
return &deflectCreateCB;
}
void DeflectObject::InvalidateUI()
{
if (pmapParam) pmapParam->Invalidate();
}
ParamDimension *DeflectObject::GetParameterDim(int pbIndex)
{
switch (pbIndex) {
case 0:
default: return defaultDim;
}
}
TSTR DeflectObject::GetParameterName(int pbIndex)
{
switch (pbIndex) {
case PB_BOUNCE: return GetString(IDS_RB_BOUNCE);
case PB_WIDTH: return GetString(IDS_RB_WIDTH);
case PB_HEIGHT: return GetString(IDS_RB_LENGTH);
default: return TSTR(_T(""));
}
}
//--- DeflectMod methods -----------------------------------------------
DeflectMod::DeflectMod(INode *node,DeflectObject *obj)
{
//MakeRefByID(FOREVER,SIMPWSMMOD_OBREF,obj);
MakeRefByID(FOREVER,SIMPWSMMOD_NODEREF,node);
pblock = NULL;
obRef = NULL;
}
Interval DeflectMod::GetValidity(TimeValue t)
{
if (obRef && nodeRef) {
Interval valid = FOREVER;
Matrix3 tm;
float f;
DeflectObject *obj = (DeflectObject*)GetWSMObject(t);
obj->pblock->GetValue(PB_BOUNCE,t,f,valid);
obj->pblock->GetValue(PB_WIDTH,t,f,valid);
obj->pblock->GetValue(PB_HEIGHT,t,f,valid);
tm = nodeRef->GetObjectTM(t,&valid);
return valid;
} else {
return FOREVER;
}
}
class DeflectDeformer : public Deformer {
public:
Point3 Map(int i, Point3 p) {return p;}
};
static DeflectDeformer ddeformer;
Deformer& DeflectMod::GetDeformer(
TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
{
return ddeformer;
}
RefTargetHandle DeflectMod::Clone(RemapDir& remap)
{
DeflectMod *newob = new DeflectMod(nodeRef,(DeflectObject*)obRef);
newob->SimpleWSMModClone(this);
return newob;
}
void DeflectMod::ModifyObject(
TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
ParticleObject *obj = GetParticleInterface(os->obj);
if (obj) {
deflect.obj = (DeflectObject*)GetWSMObject(t);
deflect.node = nodeRef;
deflect.tmValid.SetEmpty();
obj->ApplyCollisionObject(&deflect);
}
}
BOOL DeflectorField::CheckCollision(
TimeValue t,Point3 &pos, Point3 &vel, float dt, int index)
{
if (!tmValid.InInterval(t)) {
tmValid = FOREVER;
tm = node->GetObjectTM(t,&tmValid);
invtm = Inverse(tm);
}
Point3 p, v, ph;
float width, height, at, bounce;
obj->pblock->GetValue(PB_WIDTH,t,width,FOREVER);
obj->pblock->GetValue(PB_HEIGHT,t,height,FOREVER);
obj->pblock->GetValue(PB_BOUNCE,t,bounce,FOREVER);
width *= 0.5f;
height *= 0.5f;
// Transform the point and velocity into our space
p = pos * invtm;
v = VectorTransform(invtm,vel);
// Compute the point of intersection
if (fabs(p.z)<0.001) {
// We're sitting on the ground plane, just take the Z component
// out of the velocity
v.z = 0.0f;
at = 0.0f;
} else {
if (v.z==0.0) return FALSE;
at = -p.z/v.z;
if (at<0.0f || at>dt) return FALSE;
}
ph = p + at*v;
// See if the point is within our range
if (ph.x<-width || ph.x>width || ph.y<-height || ph.y>height) return FALSE;
// Remove the part of dt we used to get to the collision point
dt -= at;
// Reflect the velocity about the XY plane and attenuate with the bounce factor
v.z = -v.z;
if (bounce!=1.0f) v = v*bounce;
// Use up the rest of the dt
ph += v * dt;
// Tranform back into world space.
pos = ph * tm;
vel = VectorTransform(tm,v);
return TRUE;
}
@@ -0,0 +1,88 @@
/**********************************************************************
*<
FILE: delmod.cpp
DESCRIPTION: A deletion modifier
CREATED BY: Rolf Berteig
HISTORY: 10/23/96
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
class DeleteMod : public Modifier {
public:
DeleteMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) {s = GetString(IDS_RB_DELETEMOD);}
virtual Class_ID ClassID() { return Class_ID(DELETE_CLASS_ID,0);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_DELETEMOD);}
// From modifier
ChannelMask ChannelsUsed() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_SUBSEL_TYPE|PART_VERTCOLOR|TEXMAP_CHANNEL;}
ChannelMask ChannelsChanged() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_VERTCOLOR|TEXMAP_CHANNEL;}
Class_ID InputType() {return triObjectClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t) {return FOREVER;}
// From BaseObject
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
int NumRefs() {return 0;}
RefTargetHandle GetReference(int i) {return NULL;}
void SetReference(int i, RefTargetHandle rtarg) {}
int NumSubs() {return 0;}
Animatable* SubAnim(int i) {return NULL;}
TSTR SubAnimName(int i) {return _T("");}
RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message) {return REF_SUCCEED;}
};
//--- ClassDescriptor and class vars ---------------------------------
class DeleteClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new DeleteMod; }
const TCHAR * ClassName() { return GetString(IDS_RB_DELETEMOD); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(DELETE_CLASS_ID,0); }
const TCHAR* Category() { return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static DeleteClassDesc deleteDesc;
ClassDesc* GetDeleteModDesc() {return &deleteDesc;}
//--- Delete mod methods -------------------------------
DeleteMod::DeleteMod()
{
}
RefTargetHandle DeleteMod::Clone(RemapDir& remap)
{
return new DeleteMod();
}
void DeleteMod::ModifyObject(
TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
if (os->obj->IsSubClassOf(triObjectClassID)) {
TriObject *tobj = (TriObject*)os->obj;
tobj->mesh.DeleteSelected();
}
}
@@ -0,0 +1,104 @@
/**********************************************************************
*<
FILE: delmod.cpp
DESCRIPTION: A delete spline modifier
CREATED BY: Audrey Peterson
HISTORY: 1/97
*> Copyright (c) 1997, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#include "shape.h"
#include "spline3d.h"
#include "splshape.h"
#define SDELETE_CLASS_ID 0x120f2c0c
class SDeleteMod : public Modifier {
public:
SDeleteMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) {s = GetString(IDS_AP_SDELETEMOD);}
virtual Class_ID ClassID() { return Class_ID(SDELETE_CLASS_ID,0);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_AP_SDELETEMOD);}
// From modifier
ChannelMask ChannelsUsed() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_SUBSEL_TYPE;}
ChannelMask ChannelsChanged() {return PART_GEOM|PART_TOPO|PART_SELECT;}
Class_ID InputType() {return splineShapeClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t) {return FOREVER;}
// From BaseObject
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
int NumRefs() {return 0;}
RefTargetHandle GetReference(int i) {return NULL;}
void SetReference(int i, RefTargetHandle rtarg) {}
int NumSubs() {return 0;}
Animatable* SubAnim(int i) {return NULL;}
TSTR SubAnimName(int i) {return _T("");}
RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message) {return REF_SUCCEED;}
};
//--- ClassDescriptor and class vars ---------------------------------
class SDeleteClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new SDeleteMod; }
const TCHAR * ClassName() { return GetString(IDS_AP_SDELETEMOD); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(SDELETE_CLASS_ID,0); }
const TCHAR* Category() { return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static SDeleteClassDesc SdeleteDesc;
ClassDesc* GetSDeleteModDesc() {return &SdeleteDesc;}
//--- Delete mod methods -------------------------------
SDeleteMod::SDeleteMod()
{
}
RefTargetHandle SDeleteMod::Clone(RemapDir& remap)
{
return new SDeleteMod();
}
void SDeleteMod::ModifyObject(
TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{ if (os->obj->CanConvertToType(splineShapeClassID))
{ SplineShape *sshape = (SplineShape *)os->obj->ConvertToType(t,splineShapeClassID);
int ss;
switch (ss=sshape->shape.selLevel)
{ case SHAPE_OBJECT:
{ for(int poly = sshape->shape.vertSel.polys - 1; poly >= 0; --poly)
sshape->shape.vertSel[poly].SetAll();
sshape->shape.DeleteSelectedVerts();
}
break;
case SHAPE_VERTEX: sshape->shape.DeleteSelectedVerts();
break;
case SHAPE_SEGMENT: sshape->shape.DeleteSelectedSegs();
break;
case SHAPE_SPLINE: sshape->shape.DeleteSelectedPolys();
break;
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,154 @@
/**********************************************************************
*<
FILE: editsops.cpp
DESCRIPTION: Edit Shape OSM operations
CREATED BY: Tom Hudson & Rolf Berteig
HISTORY: created 25 April, 1995
*> Copyright (c) 1995, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "editpat.h"
extern CoreExport Class_ID patchClassID;
// in mods.cpp
extern HINSTANCE hInstance;
/*-------------------------------------------------------------------*/
static void XORDottedLine( HWND hwnd, IPoint2 p0, IPoint2 p1 )
{
HDC hdc;
hdc = GetDC( hwnd );
SetROP2( hdc, R2_XORPEN );
SetBkMode( hdc, TRANSPARENT );
SelectObject( hdc, CreatePen( PS_DOT, 0, RGB(255,255,255) ) );
MoveToEx( hdc, p0.x, p0.y, NULL );
LineTo( hdc, p1.x, p1.y );
DeleteObject( SelectObject( hdc, GetStockObject( BLACK_PEN ) ) );
ReleaseDC( hwnd, hdc );
}
/*-------------------------------------------------------------------*/
EPTempData::~EPTempData()
{
if (adjList) delete adjList;
if (vertCluster) delete vertCluster;
if (cnormals) delete cnormals;
if (ccenters) delete ccenters;
if (vnormals) delete vnormals;
if (patch) delete patch;
}
EPTempData::EPTempData(EditPatchMod *m,EditPatchData *pd)
{
adjList = NULL;
vertCluster = NULL;
cnormals = NULL;
ccenters = NULL;
patch = NULL;
alValid.SetEmpty();
patchValid.SetEmpty();
patchData = pd;
mod = m;
vnormals = NULL;
}
void EPTempData::Invalidate(DWORD part,BOOL patchValid)
{
if ( !patchValid ) {
delete patch;
patch = NULL;
}
if ( part & PART_TOPO ) {
if ( adjList ) delete adjList;
adjList = NULL;
if ( vertCluster ) delete vertCluster;
vertCluster = NULL;
if ( cnormals ) delete cnormals;
cnormals = NULL;
if ( ccenters ) delete ccenters;
ccenters = NULL;
if ( vnormals ) delete vnormals;
vnormals = NULL;
}
if ( part & PART_GEOM ) {
if ( cnormals ) delete cnormals;
cnormals = NULL;
if ( ccenters ) delete ccenters;
ccenters = NULL;
if ( vnormals ) delete vnormals;
vnormals = NULL;
}
if ( part & PART_SELECT ) {
if ( vertCluster ) delete vertCluster;
vertCluster = NULL;
if ( cnormals ) delete cnormals;
cnormals = NULL;
if ( ccenters ) delete ccenters;
ccenters = NULL;
}
}
PatchMesh *EPTempData::GetPatch(TimeValue t)
{
if ( patchValid.InInterval(t) && patch ) {
return patch;
} else {
patchData->SetFlag(EPD_UPDATING_CACHE,TRUE);
mod->NotifyDependents(Interval(t,t),
PART_GEOM|SELECT_CHANNEL|PART_SUBSEL_TYPE|PART_DISPLAY|PART_TOPO,
REFMSG_MOD_EVAL);
patchData->SetFlag(EPD_UPDATING_CACHE,FALSE);
return patch;
}
}
AdjEdgeList *EPTempData::AdjList(TimeValue t)
{
GetPatch(t);
if ( !alValid.InInterval(t) && adjList ) {
delete adjList;
adjList = NULL;
if ( vertCluster ) {
delete vertCluster;
vertCluster = NULL;
}
if ( cnormals ) {
delete cnormals;
cnormals = NULL;
}
if ( ccenters ) {
delete ccenters;
ccenters = NULL;
}
}
return adjList;
}
BOOL EPTempData::PatchCached(TimeValue t)
{
return (patchValid.InInterval(t) && patch);
}
void EPTempData::UpdateCache(PatchObject *patchOb)
{
if ( patch ) delete patch;
patch = new PatchMesh(patchOb->patch);
patchValid = FOREVER;
// These are the channels we care about.
patchValid &= patchOb->ChannelValidity(0,GEOM_CHAN_NUM);
patchValid &= patchOb->ChannelValidity(0,TOPO_CHAN_NUM);
patchValid &= patchOb->ChannelValidity(0,SELECT_CHAN_NUM);
patchValid &= patchOb->ChannelValidity(0,SUBSEL_TYPE_CHAN_NUM);
patchValid &= patchOb->ChannelValidity(0,DISP_ATTRIB_CHAN_NUM);
patchValid &= patchOb->ChannelValidity(0,TEXMAP_CHAN_NUM);
}
@@ -0,0 +1,890 @@
/**********************************************************************
*<
FILE: editsops.cpp
DESCRIPTION: Edit BezierShape OSM operations
CREATED BY: Tom Hudson & Rolf Berteig
HISTORY: created 25 April, 1995
*> Copyright (c) 1995, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "editspl.h"
#include "evrouter.h"
extern CoreExport Class_ID splineShapeClassID;
// in mods.cpp
extern HINSTANCE hInstance;
/*-------------------------------------------------------------------*/
static void XORDottedLine( HWND hwnd, IPoint2 p0, IPoint2 p1 )
{
HDC hdc;
hdc = GetDC( hwnd );
SetROP2( hdc, R2_XORPEN );
SetBkMode( hdc, TRANSPARENT );
SelectObject( hdc, CreatePen( PS_DOT, 0, RGB(255,255,255) ) );
MoveToEx( hdc, p0.x, p0.y, NULL );
LineTo( hdc, p1.x, p1.y );
DeleteObject( SelectObject( hdc, GetStockObject( BLACK_PEN ) ) );
ReleaseDC( hwnd, hdc );
}
/*-------------------------------------------------------------------*/
ESTempData::~ESTempData()
{
if (adjList) delete adjList;
if (vertCluster) delete vertCluster;
if (cnormals) delete cnormals;
if (ccenters) delete ccenters;
if (vnormals) delete vnormals;
if (shape) delete shape;
}
ESTempData::ESTempData(EditSplineMod *m,EditSplineData *sd)
{
adjList = NULL;
vertCluster = NULL;
cnormals = NULL;
ccenters = NULL;
shape = NULL;
alValid.SetEmpty();
shapeValid.SetEmpty();
shapeData = sd;
mod = m;
vnormals = NULL;
}
void ESTempData::Invalidate(DWORD part,BOOL shapeValid)
{
if ( !shapeValid ) {
delete shape;
shape = NULL;
}
if ( part & PART_TOPO ) {
if ( adjList ) delete adjList;
adjList = NULL;
if ( vertCluster ) delete vertCluster;
vertCluster = NULL;
if ( cnormals ) delete cnormals;
cnormals = NULL;
if ( ccenters ) delete ccenters;
ccenters = NULL;
if ( vnormals ) delete vnormals;
vnormals = NULL;
}
if ( part & PART_GEOM ) {
if ( cnormals ) delete cnormals;
cnormals = NULL;
if ( ccenters ) delete ccenters;
ccenters = NULL;
if ( vnormals ) delete vnormals;
vnormals = NULL;
}
if ( part & PART_SELECT ) {
if ( vertCluster ) delete vertCluster;
vertCluster = NULL;
if ( cnormals ) delete cnormals;
cnormals = NULL;
if ( ccenters ) delete ccenters;
ccenters = NULL;
}
}
BezierShape *ESTempData::GetShape(TimeValue t)
{
if ( shapeValid.InInterval(t) && shape ) {
return shape;
} else {
shapeData->SetFlag(ESD_UPDATING_CACHE,TRUE);
mod->NotifyDependents(Interval(t,t),
PART_GEOM|SELECT_CHANNEL|PART_SUBSEL_TYPE|
PART_DISPLAY|PART_TOPO, REFMSG_MOD_EVAL);
shapeData->SetFlag(ESD_UPDATING_CACHE,FALSE);
return shape;
}
}
AdjEdgeList *ESTempData::AdjList(TimeValue t)
{
GetShape(t);
if ( !alValid.InInterval(t) && adjList ) {
delete adjList;
adjList = NULL;
if ( vertCluster ) {
delete vertCluster;
vertCluster = NULL;
}
if ( cnormals ) {
delete cnormals;
cnormals = NULL;
}
if ( ccenters ) {
delete ccenters;
ccenters = NULL;
}
}
return adjList;
}
BOOL ESTempData::ShapeCached(TimeValue t)
{
return (shapeValid.InInterval(t) && shape);
}
void ESTempData::UpdateCache(SplineShape *splShape)
{
if ( shape ) delete shape;
shape = new BezierShape(splShape->shape);
shapeValid = FOREVER;
// These are the chanels we care about.
shapeValid &= splShape->ChannelValidity(0,GEOM_CHAN_NUM);
shapeValid &= splShape->ChannelValidity(0,TOPO_CHAN_NUM);
shapeValid &= splShape->ChannelValidity(0,SELECT_CHAN_NUM);
shapeValid &= splShape->ChannelValidity(0,SUBSEL_TYPE_CHAN_NUM);
shapeValid &= splShape->ChannelValidity(0,DISP_ATTRIB_CHAN_NUM);
}
HCURSOR OutlineSelectionProcessor::GetTransformCursor()
{
static HCURSOR hCur = NULL;
if ( !hCur ) {
hCur = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_OUTLINECUR));
}
return hCur;
}
/*-------------------------------------------------------------------*/
HCURSOR SegBreakMouseProc::GetTransformCursor()
{
static HCURSOR hCur = NULL;
if ( !hCur ) {
hCur = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_SEGBREAKCUR));
}
return hCur;
}
BOOL SegBreakMouseProc::HitTest(
ViewExp *vpt, IPoint2 *p, int type, int flags )
{
vpt->ClearSubObjHitList();
iObjParams->SubObHitTest(iObjParams->GetTime(),type,iObjParams->GetCrossing(),flags,p,vpt);
if ( vpt->NumSubObjHits() ) {
return TRUE;
} else {
return FALSE;
}
}
int SegBreakMouseProc::proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m )
{
ViewExp *vpt = iObjParams->GetViewport(hwnd);
int res = TRUE;
switch ( msg ) {
case MOUSE_PROPCLICK:
iObjParams->SetStdCommandMode(CID_OBJMOVE);
break;
case MOUSE_POINT:
if(HitTest(vpt,&m,HITTYPE_POINT,0) ) {
HitLog &hits = vpt->GetSubObjHitList();
HitRecord *rec = hits.First();
HitRecord *bestRec = rec;
DWORD best = rec->distance;
while(rec) {
rec = rec->Next();
if(rec) {
if(rec->distance < best) {
best = rec->distance;
bestRec = rec;
}
}
}
ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData);
es->DoSegBreak(vpt, hit->shape, hit->poly, hit->index, m);
}
res = FALSE;
break;
case MOUSE_FREEMOVE:
if ( HitTest(vpt,&m,HITTYPE_POINT,HIT_ABORTONHIT) ) {
SetCursor(GetTransformCursor());
}
else {
SetCursor(LoadCursor(NULL,IDC_ARROW));
}
break;
}
if ( vpt ) iObjParams->ReleaseViewport(vpt);
return res;
}
/*-------------------------------------------------------------------*/
HCURSOR SegRefineMouseProc::GetTransformCursor()
{
static HCURSOR hCur = NULL;
if ( !hCur ) {
hCur = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_SEGREFINECUR));
}
return hCur;
}
BOOL SegRefineMouseProc::HitTest(
ViewExp *vpt, IPoint2 *p, int type, int flags )
{
vpt->ClearSubObjHitList();
SetSplineHitOverride(ES_SEGMENT);
iObjParams->SubObHitTest(iObjParams->GetTime(),type,iObjParams->GetCrossing(),flags,p,vpt);
ClearSplineHitOverride();
if ( vpt->NumSubObjHits() ) {
return TRUE;
} else {
return FALSE;
}
}
int SegRefineMouseProc::proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m )
{
ViewExp *vpt = iObjParams->GetViewport(hwnd);
int res = TRUE;
switch ( msg ) {
case MOUSE_PROPCLICK:
iObjParams->SetStdCommandMode(CID_OBJMOVE);
break;
case MOUSE_POINT:
if(HitTest(vpt,&m,HITTYPE_POINT,0) ) {
HitLog &hits = vpt->GetSubObjHitList();
HitRecord *rec = hits.First();
HitRecord *bestRec = rec;
DWORD best = rec->distance;
while(rec) {
rec = rec->Next();
if(rec) {
if(rec->distance < best) {
best = rec->distance;
bestRec = rec;
}
}
}
ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData);
es->DoSegRefine(vpt, hit->shape, hit->poly, hit->index, m);
}
res = FALSE;
break;
case MOUSE_FREEMOVE:
if ( HitTest(vpt,&m,HITTYPE_POINT,HIT_ABORTONHIT) ) {
SetCursor(GetTransformCursor());
}
else {
SetCursor(LoadCursor(NULL,IDC_ARROW));
}
break;
}
if ( vpt ) iObjParams->ReleaseViewport(vpt);
return res;
}
/*-------------------------------------------------------------------*/
HCURSOR VertConnectMouseProc::GetTransformCursor()
{
static HCURSOR hCur = NULL;
if ( !hCur ) {
hCur = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_VERTCONNECTCUR));
}
return hCur;
}
BOOL VertConnectMouseProc::HitTest(
ViewExp *vpt, IPoint2 *p, int type, int flags )
{
vpt->ClearSubObjHitList();
iObjParams->SubObHitTest(iObjParams->GetTime(),type,iObjParams->GetCrossing(),flags,p,vpt);
if ( vpt->NumSubObjHits() ) {
return TRUE;
} else {
return FALSE;
}
}
BOOL VertConnectMouseProc::HitAnEndpoint(ViewExp *vpt, IPoint2 *p, BezierShape *shape, int poly, int vert,
BezierShape **shapeOut, int *polyOut, int *vertOut) {
int first = 1;
if(HitTest(vpt, p, HITTYPE_POINT, 0) ) {
HitLog &hits = vpt->GetSubObjHitList();
HitRecord *rec = hits.First();
DWORD best = 9999;
HitRecord *bestRec;
while(rec) {
ShapeHitData *hit = ((ShapeHitData *)rec->hitData);
// If there's an exclusion shape, this must be a part of it!
if(!shape || shape == hit->shape) {
// If there's an exclusion shape, the vert & poly can't be the same!
if(!shape || (shape && !(poly == hit->poly && vert == hit->index))) {
Spline3D *spline = hit->shape->splines[hit->poly];
if(!spline->Closed()) {
int hitKnot = hit->index / 3;
if(hitKnot == 0 || hitKnot == (spline->KnotCount() - 1)) {
if(first || rec->distance < best) {
first = 0;
best = rec->distance;
bestRec = rec;
}
}
}
}
}
rec = rec->Next();
}
if(!first) {
ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData);
if(shapeOut)
*shapeOut = hit->shape;
if(polyOut)
*polyOut = hit->poly;
if(vertOut)
*vertOut = hit->index;
return TRUE;
}
}
return FALSE;
}
int VertConnectMouseProc::proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m )
{
ViewExp *vpt = iObjParams->GetViewport(hwnd);
int res = TRUE;
static BezierShape *shape1 = NULL;
static int poly1, vert1, poly2, vert2;
static IPoint2 anchor, lastPoint;
switch ( msg ) {
case MOUSE_PROPCLICK:
iObjParams->SetStdCommandMode(CID_OBJMOVE);
break;
case MOUSE_POINT:
switch(point) {
case 0:
if(HitAnEndpoint(vpt, &m, NULL, -1, -1, &shape1, &poly1, &vert1))
res = TRUE;
else
res = FALSE;
anchor = lastPoint = m;
XORDottedLine(hwnd, anchor, m); // Draw it!
break;
case 1:
XORDottedLine(hwnd, anchor, lastPoint); // Erase it!
if(HitAnEndpoint(vpt, &m, shape1, poly1, vert1, NULL, &poly2, &vert2))
es->DoVertConnect(vpt, shape1, poly1, vert1, poly2, vert2);
res = FALSE;
break;
default:
assert(0);
}
break;
case MOUSE_MOVE:
// Erase old dotted line
XORDottedLine(hwnd, anchor, lastPoint);
// Draw new dotted line
XORDottedLine(hwnd, anchor, m);
lastPoint = m;
if(HitAnEndpoint(vpt, &m, shape1, poly1, vert1, NULL, NULL, NULL))
SetCursor(GetTransformCursor());
else
SetCursor(LoadCursor(NULL,IDC_ARROW));
break;
case MOUSE_FREEMOVE:
if ( HitTest(vpt,&m,HITTYPE_POINT,HIT_ABORTONHIT) ) {
HitLog &hits = vpt->GetSubObjHitList();
HitRecord *rec = hits.First();
ShapeHitData *hit = ((ShapeHitData *)rec->hitData);
Spline3D *spline = hit->shape->splines[hit->poly];
if(!spline->Closed()) {
int hitKnot = hit->index / 3;
if(hitKnot == 0 || hitKnot == (spline->KnotCount() - 1)) {
SetCursor(LoadCursor(hInstance,MAKEINTRESOURCE(IDC_TH_SELCURSOR)));
break;
}
}
}
SetCursor(LoadCursor(NULL,IDC_ARROW));
break;
case MOUSE_ABORT:
// Erase old dotted line
XORDottedLine(hwnd, anchor, lastPoint);
break;
}
if ( vpt ) iObjParams->ReleaseViewport(vpt);
return res;
}
/*-------------------------------------------------------------------*/
HCURSOR VertInsertMouseProc::GetTransformCursor()
{
static HCURSOR hCur = NULL;
if ( !hCur ) {
hCur = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_VERTINSERTCUR));
}
return hCur;
}
BOOL VertInsertMouseProc::HitTest(
ViewExp *vpt, IPoint2 *p, int type, int flags, int hitType )
{
vpt->ClearSubObjHitList();
SetSplineHitOverride(hitType);
iObjParams->SubObHitTest(iObjParams->GetTime(),type,iObjParams->GetCrossing(),flags,p,vpt);
ClearSplineHitOverride();
if ( vpt->NumSubObjHits() )
return TRUE;
return FALSE;
}
// Determine where we'll be inserting. If they clicked on an endpoint, fill in 'vertOut'.
// If they clicked on a segment, fill in 'segOut'.
BOOL VertInsertMouseProc::InsertWhere(ViewExp *vpt, IPoint2 *p, BezierShape **shapeOut, int *polyOut,
int *segOut, int *vertOut) {
int first = 1;
// Reset these!
*segOut = -1;
*vertOut = -1;
// Only valid insertion vertices are endpoints of the spline
if(HitTest(vpt, p, HITTYPE_POINT, 0, ES_VERTEX) ) {
HitLog &hits = vpt->GetSubObjHitList();
HitRecord *rec = hits.First();
DWORD best = 9999;
HitRecord *bestRec;
while(rec) {
ShapeHitData *hit = ((ShapeHitData *)rec->hitData);
int hitKnot = hit->index / 3;
Spline3D *spline = hit->shape->splines[hit->poly];
if(!spline->Closed() && (hitKnot == 0 || hitKnot == (spline->KnotCount() - 1))) {
if(first || rec->distance < best) {
first = 0;
best = rec->distance;
bestRec = rec;
}
}
rec = rec->Next();
}
if(!first) {
ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData);
if(shapeOut)
*shapeOut = hit->shape;
if(polyOut)
*polyOut = hit->poly;
if(vertOut)
*vertOut = hit->index;
return TRUE;
}
}
// No hits on endpoints, so let's try segments!
if(HitTest(vpt, p, HITTYPE_POINT, 0, ES_SEGMENT) ) {
HitLog &hits = vpt->GetSubObjHitList();
HitRecord *rec = hits.First();
DWORD best = 9999;
HitRecord *bestRec;
while(rec) {
ShapeHitData *hit = ((ShapeHitData *)rec->hitData);
if(first || rec->distance < best) {
first = 0;
best = rec->distance;
bestRec = rec;
}
rec = rec->Next();
}
if(!first) {
ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData);
if(shapeOut)
*shapeOut = hit->shape;
if(polyOut)
*polyOut = hit->poly;
if(segOut)
*segOut = hit->index;
return TRUE;
}
}
return FALSE;
}
class ESIBackspaceUser : public EventUser {
Spline3D *spline;
EditSplineMod *mod;
public:
void Notify();
void SetPtrs(EditSplineMod *m,Spline3D *s) { mod = m; spline = s; }
};
void ESIBackspaceUser::Notify() {
if(spline->KnotCount() > 2) {
// Tell the spline we just backspaced to remove the last point
spline->Create(NULL, -1, 0, 0, IPoint2(0,0), NULL);
mod->insertShapeData->Invalidate(PART_GEOM);
mod->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE);
mod->iObjParams->RedrawViews(mod->iObjParams->GetTime(), REDRAW_NORMAL);
}
}
static ESIBackspaceUser iBack;
int VertInsertMouseProc::proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m )
{
ViewExp *vpt = iObjParams->GetViewport(hwnd);
int res = TRUE;
static int poly, seg, vert;
static BezierShape *shape;
static int inserting = FALSE;
static Matrix3 mat;
static EditSplineMod *mod;
static int waitForButtonUp;
if(inserting) {
if(waitForButtonUp) {
if(flags & MOUSE_LBUTTON)
return TRUE;
waitForButtonUp = FALSE;
}
int res = shape->splines[poly]->Create(vpt,msg,point,flags,m,&mat,iObjParams);
// Must update the shape's selection set for this spline
BitArray& vsel = shape->vertSel[poly];
BitArray& ssel = shape->segSel[poly];
while(vsel.GetSize() < shape->splines[poly]->Verts()) {
vsel.SetSize(vsel.GetSize() + 3,1);
vsel.Shift(RIGHT_BITSHIFT,3,vert+3);
vsel.Clear(vert+2);
vsel.Clear(vert+3);
vsel.Clear(vert+4);
}
while(ssel.GetSize() < shape->splines[poly]->Segments()) {
ssel.SetSize(ssel.GetSize() + 1,1);
ssel.Shift(RIGHT_BITSHIFT,1,vert/3+1);
ssel.Clear(vert/3+1);
}
switch(res) {
case CREATE_STOP: {
// Must update the shape's selection set for this spline
BitArray& vsel = shape->vertSel[poly];
BitArray& ssel = shape->segSel[poly];
while(vsel.GetSize() > shape->splines[poly]->Verts()) {
vsel.Shift(LEFT_BITSHIFT,3,vert+1);
vsel.SetSize(vsel.GetSize() - 3,1);
}
while(ssel.GetSize() > shape->splines[poly]->Segments()) {
ssel.Shift(LEFT_BITSHIFT,1,(vert+1)/3);
ssel.SetSize(ssel.GetSize() - 1,1);
}
es->EndVertInsert();
inserting = FALSE;
backspaceRouter.UnRegister(&iBack);
break;
}
}
mod->insertShapeData->Invalidate(PART_GEOM);
mod->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE);
iObjParams->RedrawViews(iObjParams->GetTime(), REDRAW_NORMAL);
}
else {
switch(msg) {
case MOUSE_PROPCLICK:
iObjParams->SetStdCommandMode(CID_OBJMOVE);
break;
case MOUSE_POINT:
if(InsertWhere(vpt, &m, &shape, &poly, &seg, &vert)) {
vert = es->StartVertInsert(vpt, shape, poly, seg, vert, &mod);
if(vert < 0) {
res = FALSE;
break;
}
mat = mod->insertTM;
shape->splines[poly]->StartInsert(vpt, msg, point, flags, m, &mat, vert/3+1 );
// Must update the shape's selection set for this spline
BitArray& vsel = shape->vertSel[poly];
BitArray& ssel = shape->segSel[poly];
while(vsel.GetSize() < shape->splines[poly]->Verts()) {
vsel.SetSize(vsel.GetSize() + 3,1);
vsel.Shift(RIGHT_BITSHIFT,3,vert+3);
vsel.Clear(vert+2);
vsel.Clear(vert+3);
vsel.Clear(vert+4);
}
while(ssel.GetSize() < shape->splines[poly]->Segments()) {
ssel.SetSize(ssel.GetSize() + 1,1);
ssel.Shift(RIGHT_BITSHIFT,1,vert/3+1);
ssel.Clear(vert/3+1);
}
inserting = TRUE;
waitForButtonUp = TRUE;
iBack.SetPtrs(mod, shape->splines[poly]);
backspaceRouter.Register(&iBack);
}
else
res = FALSE;
break;
case MOUSE_MOVE:
case MOUSE_ABORT:
res = FALSE;
break;
case MOUSE_FREEMOVE:
if ( HitTest(vpt, &m, HITTYPE_POINT, HIT_ABORTONHIT, ES_VERTEX) )
SetCursor(GetTransformCursor());
else
if ( HitTest(vpt, &m, HITTYPE_POINT, HIT_ABORTONHIT, ES_SEGMENT) )
SetCursor(GetTransformCursor());
else
SetCursor(LoadCursor(NULL,IDC_ARROW));
break;
}
}
if ( vpt ) iObjParams->ReleaseViewport(vpt);
return res;
}
/*-------------------------------------------------------------------*/
class ESMBackspaceUser : public EventUser {
Spline3D *spline;
EditSplineMod *mod;
public:
void Notify();
void SetPtrs(EditSplineMod *m,Spline3D *s) { mod = m; spline = s; }
};
void ESMBackspaceUser::Notify() {
if(spline->KnotCount() > 2) {
// Tell the spline we just backspaced to remove the last point
spline->Create(NULL, -1, 0, 0, IPoint2(0,0), NULL);
mod->createShapeData->Invalidate(PART_GEOM);
mod->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE);
mod->iObjParams->RedrawViews(mod->iObjParams->GetTime(), REDRAW_NORMAL);
}
}
static ESMBackspaceUser pBack;
int CreateLineMouseProc::proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m )
{
ViewExp *vpt = iObjParams->GetViewport(hwnd);
int res = TRUE;
static int poly, seg, vert;
static BezierShape *shape;
static Spline3D *spline;
static int inserting = FALSE;
static Matrix3 mat;
static EditSplineMod *mod;
static int waitForButtonUp;
if(inserting) {
if(waitForButtonUp) {
if(flags & MOUSE_LBUTTON)
return TRUE;
waitForButtonUp = FALSE;
}
vpt->getGW()->setTransform(mat);
int res = shape->splines[poly]->Create(vpt,msg,point,flags,m,&mat,iObjParams);
// Must update the shape's selection set for this spline
shape->UpdateSels();
switch(res) {
case CREATE_STOP:
es->EndCreateLine();
inserting = FALSE;
backspaceRouter.UnRegister(&pBack);
break;
case CREATE_ABORT:
shape->DeleteSpline(poly);
inserting = FALSE;
backspaceRouter.UnRegister(&pBack);
break;
}
mod->createShapeData->Invalidate(PART_GEOM);
mod->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE);
iObjParams->RedrawViews(iObjParams->GetTime(), REDRAW_NORMAL);
}
else {
switch(msg) {
case MOUSE_PROPCLICK:
iObjParams->SetStdCommandMode(CID_OBJMOVE);
break;
case MOUSE_POINT:
mod = es;
if(!mod->StartCreateLine(&shape))
return CREATE_ABORT;
poly = shape->splineCount;
spline = shape->NewSpline();
mat = mod->createTM;
vpt->getGW()->setTransform(mat);
if(spline->Create(vpt,msg,point,flags,m,&mat,iObjParams) == CREATE_CONTINUE) {
inserting = TRUE;
waitForButtonUp = TRUE;
shape->UpdateSels();
pBack.SetPtrs(mod, spline);
backspaceRouter.Register(&pBack);
}
else {
shape->DeleteSpline(poly);
res = FALSE;
}
break;
case MOUSE_MOVE:
case MOUSE_ABORT:
res = FALSE;
break;
case MOUSE_FREEMOVE:
SetCursor(LoadCursor(NULL,IDC_ARROW));
#ifdef _OSNAP
vpt->SnapPreview(m,m,NULL, SNAP_IN_3D);
#endif
break;
}
}
if ( vpt ) iObjParams->ReleaseViewport(vpt);
return res;
}
/*-------------------------------------------------------------------*/
HCURSOR BooleanMouseProc::GetTransformCursor()
{
return LoadCursor(hInstance, MAKEINTRESOURCE(es->GetBoolCursorID()));
}
BOOL BooleanMouseProc::HitTest(
ViewExp *vpt, IPoint2 *p, int type, int flags )
{
vpt->ClearSubObjHitList();
iObjParams->SubObHitTest(iObjParams->GetTime(),type,iObjParams->GetCrossing(),flags,p,vpt);
if ( vpt->NumSubObjHits() )
return TRUE;
return FALSE;
}
int BooleanMouseProc::proc(
HWND hwnd,
int msg,
int point,
int flags,
IPoint2 m )
{
ViewExp *vpt = iObjParams->GetViewport(hwnd);
int res = TRUE;
static int poly2 = -1;
switch(msg) {
case MOUSE_PROPCLICK:
iObjParams->SetStdCommandMode(CID_OBJMOVE);
break;
case MOUSE_POINT:
if(poly2 >= 0)
if(ValidBooleanPolygon(es->iObjParams, es->boolShape->splines[poly2]))
es->DoBoolean(poly2);
res = FALSE;
break;
case MOUSE_MOVE:
case MOUSE_ABORT:
res = FALSE;
break;
case MOUSE_FREEMOVE:
poly2 = -1;
if ( HitTest(vpt,&m,HITTYPE_POINT,HIT_ABORTONHIT) ) {
HitLog &hits = vpt->GetSubObjHitList();
HitRecord *rec = hits.First();
ShapeHitData *hit = ((ShapeHitData *)rec->hitData);
Spline3D *spline = hit->shape->splines[hit->poly];
if(spline->Closed() && hit->shape == es->boolShape && hit->poly != es->boolPoly1) {
poly2 = hit->poly;
SetCursor(GetTransformCursor());
break;
}
}
SetCursor(LoadCursor(NULL,IDC_ARROW));
break;
}
if ( vpt ) iObjParams->ReleaseViewport(vpt);
return res;
}
/*-------------------------------------------------------------------*/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,113 @@
/**********************************************************************
*<
FILE: edmdata.h
DESCRIPTION: Some stuff used by the edit mesh modifier that is
useful for some of the other modifiers
CREATED BY: Rolf Berteig
HISTORY: created 18 March, 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#ifndef __EDMDATA__
#define __EDMDATA__
class AdjEdgeList;
class AdjFaceList;
#ifndef UNDEFINED
#define UNDEFINED 0xffffffff
#endif
class MEdge {
public:
DWORD f[2];
DWORD v[2];
int EdgeIndex(Face *faces,int side);
BOOL Selected(Face *faces,BitArray &esel);
Point3 Center(Point3 *verts);
Point3 ButterFlySubdivide(Mesh *mesh,AdjFaceList *af,float tens);
BOOL AFaceSelected(BitArray &fsel);
};
class AdjEdgeList {
public:
DWORDTab *list; // 1 DWORDTab per vertex. The Tab is a list of indices into the edge list, 1 for each edge adjacent to the vertex
Tab<MEdge> edges; // Table of edges
int nverts; // size of 'list'.
AdjEdgeList(Mesh& amesh);
~AdjEdgeList();
AdjEdgeList& operator=(AdjEdgeList& a) {assert(0);return *this;}
void AddEdge( DWORD fi, DWORD v1, DWORD v2 );
DWORDTab& operator[](int i) { return list[i]; }
int FindEdge(DWORD v0, DWORD v1);
void RemoveEdgeFromVertex(DWORD v,DWORD e);
void AddEdgeToVertex(DWORD v,DWORD e);
};
class AdjFace {
public:
DWORD f[3];
AdjFace() { f[0] = f[1] = f[2] = UNDEFINED; }
};
class AdjFaceList {
public:
Tab<AdjFace> list;
AdjFace& operator[](int i) { return list[i]; }
AdjFaceList(Mesh& mesh,AdjEdgeList& el);
};
class FaceClusterList {
public:
// Cluster #, one for each face - non-selected faces have UNDEFINED for their id.
DWORDTab clust;
DWORD count;
// This version separates cluster also using a minimum angle and optionally the selection set
FaceClusterList(Mesh *mesh, AdjFaceList& adj,float angle,BOOL useSel=TRUE);
void ClusterID(Mesh *mesh, int f, AdjFaceList& adj, DWORD id, float angle,BOOL useSel);
// Uses selection set
FaceClusterList(BitArray& fsel, AdjFaceList& adj);
void ClusterID(int f,BitArray& fsel, AdjFaceList& adj, DWORD id);
DWORD operator[](int i) { return clust[i]; }
void MakeVertCluster(Mesh &mesh,DWORDTab& vclust);
};
class EdgeClusterList {
public:
DWORDTab clust;
DWORD count;
EdgeClusterList(Mesh &mesh,BitArray &esel,AdjEdgeList &adj);
BOOL ClusterID(Mesh& mesh, int index, BitArray& esel, AdjEdgeList& adj, DWORD id);
DWORD ID(int f, int e) {return clust[f*3+e];}
DWORD operator[](int i) {return clust[i];}
void MakeVertCluster(Mesh &mesh,DWORDTab& vclust);
};
class FaceElementList {
public:
// For each face, which element is it in
DWORDTab elem;
DWORD count;
FaceElementList(Mesh &mesh,AdjFaceList& af);
void AddFacesToElem(int face,Mesh &mesh,AdjFaceList& af,DWORD e);
DWORD operator[](int i) {return elem[i];}
};
void FlipMeshNormal(Mesh *mesh,DWORD face);
#endif // __EDMDATA__
@@ -0,0 +1,408 @@
/**********************************************************************
*<
FILE: edmrest.cpp
DESCRIPTION: Edit Mesh OSM Restore objects
CREATED BY: Rolf Berteig
HISTORY: created 1 September, 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "editmesh.h"
VertexEditRestore::VertexEditRestore(EditMeshData* md, EditMeshMod* mod)
{
meshData = md;
this->mod = mod;
deltas = md->vdelta;
t = mod->iObjParams->GetTime();
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
verts.SetCount(mesh->getNumVerts());
for ( int i = 0; i < mesh->getNumVerts(); i++ ) {
verts[i] = mesh->verts[i];
}
}
void VertexEditRestore::Restore(int isUndo)
{
// So we can redo...
rdeltas = meshData->vdelta;
meshData->vdelta = deltas;
if (meshData->tempData && meshData->TempData(mod)->MeshCached(t)) {
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
mesh->setNumVerts(verts.Count());
for (int i = 0; i < verts.Count(); i++) {
mesh->verts[i] = verts[i];
}
mesh->vertHide = deltas.hide;
meshData->TempData(mod)->Invalidate(PART_GEOM);
} else
if (meshData->tempData) {
meshData->TempData(mod)->Invalidate(PART_GEOM,FALSE);
}
if (isUndo) mod->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE);
}
void VertexEditRestore::Redo()
{
deltas = meshData->vdelta;
meshData->vdelta = rdeltas;
rdeltas.SetSize(0);
if (meshData->tempData) {
meshData->TempData(mod)->Invalidate(PART_GEOM,FALSE);
}
mod->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE);
}
/*-------------------------------------------------------------------*/
TopoEditRestore::TopoEditRestore(EditMeshData* md, EditMeshMod* mod)
: VertexEditRestore(md,mod)
{
tdelta = md->tdelta;
vsel = md->vsel;
fsel = md->fsel;
esel = md->esel;
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
faces.SetCount(mesh->getNumFaces());
for (int i = 0; i<mesh->getNumFaces(); i++) {
faces[i] = mesh->faces[i];
}
}
void TopoEditRestore::Restore(int isUndo)
{
if (isUndo && rvsel.GetSize()!=meshData->vsel.GetSize()) {
rtdelta = meshData->tdelta;
rvsel = meshData->vsel;
rfsel = meshData->fsel;
resel = meshData->esel;
}
meshData->tdelta = tdelta;
meshData->vsel = vsel;
meshData->fsel = fsel;
meshData->esel = esel;
// RB 3-21-96: Instead of undoing the cache, invalidate it
if (0/*meshData->tempData && meshData->TempData(mod)->MeshCached(t)*/) {
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
mesh->setNumFaces(faces.Count());
for (int i = 0; i < faces.Count(); i++) {
mesh->faces[i] = faces[i];
}
mesh->faceSel = fsel;
mesh->edgeSel = esel;
meshData->TempData(mod)->Invalidate(PART_TOPO);
} else
if (meshData->tempData) {
meshData->TempData(mod)->Invalidate(PART_TOPO,FALSE);
}
VertexEditRestore::Restore(isUndo);
}
void TopoEditRestore::Redo()
{
meshData->tdelta = rtdelta;
meshData->vsel = rvsel;
meshData->fsel = rfsel;
meshData->esel = resel;
if (meshData->tempData) {
meshData->TempData(mod)->Invalidate(PART_TOPO,FALSE);
}
VertexEditRestore::Redo();
}
/*-------------------------------------------------------------------*/
VertexSelRestore::VertexSelRestore(EditMeshData* md, EditMeshMod* mod)
{
sel = md->vsel;
meshData = md;
this->mod = mod;
t = mod->iObjParams->GetTime();
}
void VertexSelRestore::Restore(int isUndo)
{
rsel = meshData->vsel;
meshData->vsel = sel;
if ( meshData->tempData && meshData->TempData(mod)->MeshCached(t) ) {
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
mesh->vertSel = sel;
meshData->TempData(mod)->Invalidate(PART_SELECT);
}
mod->NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
void VertexSelRestore::Redo()
{
meshData->vsel = rsel;
if ( meshData->tempData && meshData->TempData(mod)->MeshCached(t) ) {
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
mesh->vertSel = rsel;
meshData->TempData(mod)->Invalidate(PART_SELECT);
}
mod->NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
/*-------------------------------------------------------------------*/
VertexHideRestore::VertexHideRestore(EditMeshData* md, EditMeshMod* mod)
{
hide = md->vdelta.hide;
meshData = md;
this->mod = mod;
t = mod->iObjParams->GetTime();
}
void VertexHideRestore::Restore(int isUndo)
{
rhide = meshData->vdelta.hide;
meshData->vdelta.hide = hide;
if (meshData->tempData && meshData->TempData(mod)->MeshCached(t)) {
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
mesh->vertHide = hide;
}
mod->NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
}
void VertexHideRestore::Redo()
{
meshData->vdelta.hide = rhide;
if (meshData->tempData && meshData->TempData(mod)->MeshCached(t)) {
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
mesh->vertHide = rhide;
}
mod->NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
}
/*-------------------------------------------------------------------*/
FaceSelRestore::FaceSelRestore(EditMeshData* md, EditMeshMod* mod)
{
sel = md->fsel;
meshData = md;
this->mod = mod;
t = mod->iObjParams->GetTime();
}
void FaceSelRestore::Restore(int isUndo)
{
rsel = meshData->fsel;
meshData->fsel = sel;
if ( meshData->tempData && meshData->TempData(mod)->MeshCached(t) ) {
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
mesh->faceSel = sel;
meshData->TempData(mod)->Invalidate(PART_SELECT);
}
mod->NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
void FaceSelRestore::Redo()
{
meshData->fsel = rsel;
if ( meshData->tempData && meshData->TempData(mod)->MeshCached(t) ) {
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
mesh->faceSel = rsel;
meshData->TempData(mod)->Invalidate(PART_SELECT);
}
mod->NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
/*-------------------------------------------------------------------*/
EdgeSelRestore::EdgeSelRestore(EditMeshData* md, EditMeshMod* mod)
{
sel = md->esel;
meshData = md;
this->mod = mod;
t = mod->iObjParams->GetTime();
}
void EdgeSelRestore::Restore(int isUndo)
{
rsel = meshData->esel;
meshData->esel = sel;
if ( meshData->tempData && meshData->TempData(mod)->MeshCached(t) ) {
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
mesh->edgeSel = sel;
meshData->TempData(mod)->Invalidate(PART_SELECT);
}
mod->NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
void EdgeSelRestore::Redo()
{
meshData->esel = rsel;
if ( meshData->tempData && meshData->TempData(mod)->MeshCached(t) ) {
Mesh *mesh = meshData->TempData(mod)->GetMesh(t);
mesh->edgeSel = rsel;
meshData->TempData(mod)->Invalidate(PART_DISPLAY);
}
mod->NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
/*-------------------------------------------------------------------*/
FaceAttribRestore::FaceAttribRestore(EditMeshData* md, EditMeshMod* mod)
{
attribs = md->tdelta.attribs;
meshData = md;
this->mod = mod;
}
void FaceAttribRestore::Restore(int isUndo)
{
if (isUndo) {
rattribs = meshData->tdelta.attribs;
}
meshData->tdelta.attribs = attribs;
if (meshData->tempData) {
meshData->TempData(mod)->Invalidate(PART_TOPO,FALSE);
}
mod->InvalidateSurfaceUI();
mod->NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
}
void FaceAttribRestore::Redo()
{
meshData->tdelta.attribs = rattribs;
if (meshData->tempData) {
meshData->TempData(mod)->Invalidate(PART_TOPO,FALSE);
}
mod->InvalidateSurfaceUI();
mod->NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
/*-------------------------------------------------------------------*/
FaceSmoothGroupRestore::FaceSmoothGroupRestore(EditMeshData* md, EditMeshMod* mod)
{
smgroups = md->tdelta.smgroups;
meshData = md;
this->mod = mod;
}
void FaceSmoothGroupRestore::Restore(int isUndo)
{
if (isUndo) {
rsmgroups = meshData->tdelta.smgroups;
}
meshData->tdelta.smgroups = smgroups;
if (meshData->tempData) {
meshData->TempData(mod)->Invalidate(PART_TOPO,FALSE);
}
mod->InvalidateSurfaceUI();
mod->NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
}
void FaceSmoothGroupRestore::Redo()
{
meshData->tdelta.smgroups = rsmgroups;
if (meshData->tempData) {
meshData->TempData(mod)->Invalidate(PART_TOPO,FALSE);
}
mod->InvalidateSurfaceUI();
mod->NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
}
/*-------------------------------------------------------------------*/
ExtrudeRestore::ExtrudeRestore(EditMeshData* md, EditMeshMod* mod)
{
meshData = md;
this->mod = mod;
}
void ExtrudeRestore::Restore(int isUndo)
{
int ct;
// Go through selected faces and put back selected faces to
// their original mapping.
int sel = 0;
for ( int i = 0; i < meshData->fsel.GetSize(); i++ ) {
if ( meshData->fsel[i] ) {
// Save for the redo
FaceMap fm = meshData->tdelta.GetFaceMap(i);
ivmap.Append(1,&fm.v[0],20);
ivmap.Append(1,&fm.v[1],20);
ivmap.Append(1,&fm.v[2],20);
// Undo
meshData->tdelta.ModifyFace(i,&vmap[sel]);
sel+=3;
}
}
ivmap.Shrink();
// Pull the verts out of tdelta
ct = meshData->tdelta.cverts.Count();
if (!cverts.Count()) {
cverts.Resize(nv);
for (i = 1; i <= nv; i++) {
DWORD v = meshData->tdelta.cverts[ct-i];
cverts.Append(1,&v);
}
}
meshData->tdelta.cverts.Delete(ct-nv,nv);
// Pull the faces out of tdelta
ct = meshData->tdelta.nfaces.Count();
if ( !nfaces.Count() ) {
nfaces.Resize(nf);
for ( i = 1; i <= nf; i++ ) {
Face f = meshData->tdelta.nfaces[ct-i];
nfaces.Append(1,&f);
}
}
meshData->tdelta.nfaces.Delete(ct-nf,nf);
meshData->Invalidate(PART_TOPO|PART_GEOM,FALSE);
mod->NotifyDependents(FOREVER, PART_TOPO|PART_GEOM, REFMSG_CHANGE);
}
void ExtrudeRestore::Redo()
{
// Go through selected faces and put back selected faces to
// their original mapping.
int sel = 0;
for ( int i = 0; i < meshData->fsel.GetSize(); i++ ) {
if ( meshData->fsel[i] ) {
// Redo
meshData->tdelta.ModifyFace(i,&ivmap[sel]);
sel+=3;
}
}
// Put the verts back into tdelta
meshData->tdelta.cverts.Resize(meshData->tdelta.cverts.Count()+nv);
for ( i = 0; i < nv; i++ ) {
meshData->tdelta.cverts.Append(1,&cverts[i]);
}
// Put the faces back into tdelta
meshData->tdelta.nfaces.Resize(meshData->tdelta.nfaces.Count()+nf);
for ( i = 0; i < nf; i++ ) {
meshData->tdelta.nfaces.Append(1,&nfaces[i]);
}
meshData->Invalidate(PART_TOPO|PART_GEOM,FALSE);
mod->NotifyDependents(FOREVER, PART_TOPO|PART_GEOM, REFMSG_CHANGE);
}
/*--------------------------------------------------------------------*/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,523 @@
/**********************************************************************
*<
FILE: fextrude.cpp
DESCRIPTION: Face Extrude Modifier
CREATED BY: Rolf Berteig
HISTORY: 10/25/96
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#include "meshadj.h"
#define PBLOCK_REF 0
#define POINT_REF 1
class FExtrudeMod : public Modifier {
public:
IParamBlock *pblock;
Control *base;
static IObjParam *ip;
static IParamMap *pmapParam;
static FExtrudeMod *editMod;
static MoveModBoxCMode *moveMode;
FExtrudeMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) {s = GetString(IDS_RB_FACEEXTRUDEMOD);}
virtual Class_ID ClassID() { return Class_ID(SUB_EXTRUDE_CLASS_ID,0);}
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip,ULONG flags,Animatable *next);
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_FACEEXTRUDEMOD);}
BOOL AssignController(Animatable *control,int subAnim);
int SubNumToRefNum(int subNum);
// From modifier
ChannelMask ChannelsUsed() {return PART_GEOM|PART_TOPO|PART_TEXMAP|PART_SELECT|PART_SUBSEL_TYPE|PART_VERTCOLOR;}
ChannelMask ChannelsChanged() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_TEXMAP|PART_VERTCOLOR;}
Class_ID InputType() {return triObjectClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t);
// From BaseObject
int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc);
int Display(TimeValue t, INode* inode, ViewExp *vpt, int flagst, ModContext *mc);
void GetWorldBoundBox(TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc);
void Move( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE );
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
void GetSubObjectCenters(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void GetSubObjectTMs(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void ActivateSubobjSel(int level, XFormModes& modes);
int NumRefs() {return 2;}
RefTargetHandle GetReference(int i);
void SetReference(int i, RefTargetHandle rtarg);
int NumSubs() {return 2;}
Animatable* SubAnim(int i) {return GetReference(i);}
TSTR SubAnimName(int i);
RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message);
Matrix3 CompMatrix(TimeValue t,INode *inode,ModContext *mc);
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *FExtrudeMod::pmapParam = NULL;
IObjParam *FExtrudeMod::ip = NULL;
FExtrudeMod *FExtrudeMod::editMod = NULL;
MoveModBoxCMode *FExtrudeMod::moveMode = NULL;
class FaceExtrudeClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new FExtrudeMod; }
const TCHAR * ClassName() { return GetString(IDS_RB_FACEEXTRUDEMOD); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(SUB_EXTRUDE_CLASS_ID,0); }
const TCHAR* Category() { return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static FaceExtrudeClassDesc fextrudeDesc;
extern ClassDesc* GetFaceExtrudeModDesc() {return &fextrudeDesc;}
//--- Parameter map/block descriptors -------------------------------
#define PB_AMOUNT 0
#define PB_SCALE 1
#define PB_CENTER 2
//
//
// Parameters
static ParamUIDesc descParam[] = {
// Amount
ParamUIDesc(
PB_AMOUNT,
EDITTYPE_FLOAT,
IDC_EXT_AMOUNT,IDC_EXT_AMOUNTSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// Scale
ParamUIDesc(
PB_SCALE,
EDITTYPE_FLOAT,
IDC_EXT_SCALE,IDC_EXT_SCALESPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// Backface
ParamUIDesc(PB_CENTER,TYPE_SINGLECHEKBOX,IDC_EXT_CENTER),
};
#define PARAMDESC_LENGTH 3
static ParamBlockDescID descVer0[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 }, // Amount
{ TYPE_FLOAT, NULL, TRUE, 1 }, // Scale
{ TYPE_INT, NULL, FALSE, 2 }, // Center
};
#define PBLOCK_LENGTH 3
#define CURRENT_VERSION 0
//--- Face extude mod methods -------------------------------
FExtrudeMod::FExtrudeMod()
{
base = NULL;
pblock = NULL;
MakeRefByID(
FOREVER, PBLOCK_REF,
CreateParameterBlock(
descVer0, PBLOCK_LENGTH, CURRENT_VERSION));
MakeRefByID(FOREVER,POINT_REF,NewDefaultPoint3Controller());
pblock->SetValue(PB_SCALE,0,100.0f);
}
void FExtrudeMod::BeginEditParams(
IObjParam *ip, ULONG flags,Animatable *prev)
{
this->ip = ip;
editMod = this;
// Add our sub object type
TSTR type1(GetString(IDS_RB_EXTRUDECENT));
const TCHAR *ptype[] = {type1};
ip->RegisterSubObjectTypes(ptype, 1);
// Create sub object editing modes.
moveMode = new MoveModBoxCMode(this,ip);
TimeValue t = ip->GetTime();
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_BEGIN_EDIT);
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_MOD_DISPLAY_ON);
SetAFlag(A_MOD_BEING_EDITED);
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGTH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_FACEEXTRUDEPARAM),
GetString(IDS_RB_PARAMETERS),
0);
}
void FExtrudeMod::EndEditParams(
IObjParam *ip,ULONG flags,Animatable *next)
{
this->ip = NULL;
editMod = NULL;
TimeValue t = ip->GetTime();
// NOTE: This flag must be cleared before sending the REFMSG_END_EDIT
ClearAFlag(A_MOD_BEING_EDITED);
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_END_EDIT);
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_MOD_DISPLAY_OFF);
ip->DeleteMode(moveMode);
if (moveMode) delete moveMode;
moveMode = NULL;
DestroyCPParamMap(pmapParam);
}
RefTargetHandle FExtrudeMod::Clone(RemapDir& remap)
{
FExtrudeMod *mod = new FExtrudeMod();
mod->ReplaceReference(PBLOCK_REF,pblock->Clone(remap));
mod->ReplaceReference(POINT_REF,base->Clone(remap));
return mod;
}
void FExtrudeMod::ModifyObject(
TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
if (os->obj->IsSubClassOf(triObjectClassID)) {
TriObject *tobj = (TriObject*)os->obj;
Mesh &mesh = tobj->mesh;
Interval iv = FOREVER;
float a, s;
Point3 pt, center;
int c;
pblock->GetValue(PB_AMOUNT,t,a,iv);
pblock->GetValue(PB_SCALE,t,s,iv);
pblock->GetValue(PB_CENTER,t,c,iv);
base->GetValue(t,&pt,iv,CTRL_ABSOLUTE);
// Extrude the faces -- this just creates the new faces
mesh.ExtrudeFaces();
// Build normals of selected faces only
Tab<Point3> normals;
if (!c) {
normals.SetCount(mesh.getNumVerts());
for (int i=0; i<mesh.getNumVerts(); i++) {
normals[i] = Point3(0,0,0);
}
for (i=0; i<mesh.getNumFaces(); i++) {
if (mesh.faceSel[i]) {
Point3 norm =
(mesh.verts[mesh.faces[i].v[1]]-mesh.verts[mesh.faces[i].v[0]]) ^
(mesh.verts[mesh.faces[i].v[2]]-mesh.verts[mesh.faces[i].v[1]]);
for (int j=0; j<3; j++) {
normals[mesh.faces[i].v[j]] += norm;
}
}
}
for (i=0; i<mesh.getNumVerts(); i++) {
normals[i] = Normalize(normals[i]);
}
} else {
// Compute the center point
base->GetValue(t,&center,iv,CTRL_ABSOLUTE);
}
// Mark vertices used by selected faces
BitArray sel;
sel.SetSize(mesh.getNumVerts());
for (int i=0; i<mesh.getNumFaces(); i++) {
if (mesh.faceSel[i]) {
for (int j=0; j<3; j++) sel.Set(mesh.faces[i].v[j],TRUE);
}
}
// Move selected verts
for (i=0; i<mesh.getNumVerts(); i++) {
if (sel[i]) {
if (!c) {
mesh.verts[i] += normals[i]*a;
} else {
Point3 vect = Normalize((mesh.verts[i] * (*mc.tm))
- center);
mesh.verts[i] += vect*a;
}
}
}
// Scale verts
if (s!=100.0f) {
s /= 100.0f;
AdjEdgeList ae(mesh);
AdjFaceList af(mesh,ae);
FaceClusterList clust(mesh.faceSel,af);
// Make sure each vertex is only scaled once.
BitArray done;
done.SetSize(mesh.getNumVerts());
// scale each cluster independently
for (int i=0; (DWORD)i<clust.count; i++) {
// First determine cluster center
Point3 cent(0,0,0);
int ct=0;
for (int j=0; j<mesh.getNumFaces(); j++) {
if (clust[j]==(DWORD)i) {
for (int k=0; k<3; k++) {
cent += mesh.verts[mesh.faces[j].v[k]];
ct++;
}
}
}
if (ct) cent /= float(ct);
// Now scale the cluster about its center
for (j=0; j<mesh.getNumFaces(); j++) {
if (clust[j]==(DWORD)i) {
for (int k=0; k<3; k++) {
int index = mesh.faces[j].v[k];
if (done[index]) continue;
done.Set(index);
mesh.verts[index] =
(mesh.verts[index]-cent)*s + cent;
}
}
}
}
}
os->obj->UpdateValidity(GEOM_CHAN_NUM,iv);
}
}
Interval FExtrudeMod::LocalValidity(TimeValue t)
{
Interval iv = FOREVER;
float v;
Point3 pt;
pblock->GetValue(PB_AMOUNT,t,v,iv);
pblock->GetValue(PB_SCALE,t,v,iv);
base->GetValue(t,&pt,iv,CTRL_ABSOLUTE);
return iv;
}
int FExtrudeMod::HitTest(
TimeValue t, INode* inode, int type, int crossing,
int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc)
{
GraphicsWindow *gw = vpt->getGW();
Point3 pt;
HitRegion hr;
int savedLimits, res = 0;
Matrix3 tm = CompMatrix(t,inode,mc);
MakeHitRegion(hr,type, crossing,4,p);
gw->setHitRegion(&hr);
gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM);
gw->setTransform(tm);
gw->clearHitCode();
base->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE);
gw->marker(&pt,HOLLOW_BOX_MRKR);
if (gw->checkHitCode()) {
vpt->LogHit(inode, mc, gw->getHitDistance(), 0, NULL);
res = 1;
}
gw->setRndLimits(savedLimits);
return res;
}
int FExtrudeMod::Display(
TimeValue t, INode* inode, ViewExp *vpt,
int flagst, ModContext *mc)
{
GraphicsWindow *gw = vpt->getGW();
Point3 pt;
Matrix3 tm = CompMatrix(t,inode,mc);
int savedLimits;
gw->setRndLimits((savedLimits = gw->getRndLimits()) & ~GW_ILLUM);
gw->setTransform(tm);
// Draw start point
if (ip && ip->GetSubObjectLevel() == 1) {
//gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
} else {
//gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS));
}
base->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE);
gw->marker(&pt,HOLLOW_BOX_MRKR);
gw->setRndLimits(savedLimits);
return 0;
}
void FExtrudeMod::GetWorldBoundBox(
TimeValue t,INode* inode, ViewExp *vpt,
Box3& box, ModContext *mc)
{
Matrix3 tm = CompMatrix(t,inode,mc);
Point3 pt;
box.Init();
base->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE);
box += pt * tm;
}
void FExtrudeMod::Move(
TimeValue t, Matrix3& partm, Matrix3& tmAxis,
Point3& val, BOOL localOrigin)
{
base->SetValue(
t,VectorTransform(tmAxis*Inverse(partm),val),
TRUE,CTRL_RELATIVE);
}
void FExtrudeMod::GetSubObjectCenters(
SubObjAxisCallback *cb,TimeValue t,
INode *node,ModContext *mc)
{
Matrix3 tm = CompMatrix(t,node,mc);
Point3 p;
base->GetValue(t,&p,FOREVER,CTRL_ABSOLUTE);
tm.PreTranslate(p);
cb->Center(tm.GetTrans(),0);
}
void FExtrudeMod::GetSubObjectTMs(
SubObjAxisCallback *cb,TimeValue t,
INode *node,ModContext *mc)
{
Matrix3 tm = CompMatrix(t,node,mc);
cb->TM(tm,0);
}
void FExtrudeMod::ActivateSubobjSel(int level, XFormModes& modes)
{
switch (level) {
case 1: // Points
modes = XFormModes(moveMode,NULL,NULL,NULL,NULL,NULL);
break;
}
NotifyDependents(FOREVER,PART_DISPLAY,REFMSG_CHANGE);
}
BOOL FExtrudeMod::AssignController(Animatable *control,int subAnim)
{
if (subAnim==POINT_REF) {
ReplaceReference(POINT_REF,(ReferenceTarget*)control);
NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
NotifyDependents(FOREVER,PART_ALL,REFMSG_SUBANIM_STRUCTURE_CHANGED);
return TRUE;
} else {
return FALSE;
}
}
int FExtrudeMod::SubNumToRefNum(int subNum)
{
if (subNum==POINT_REF) return subNum;
else return -1;
}
RefTargetHandle FExtrudeMod::GetReference(int i)
{
switch (i) {
case PBLOCK_REF: return pblock;
case POINT_REF: return base;
default: return NULL;
}
}
void FExtrudeMod::SetReference(int i, RefTargetHandle rtarg)
{
switch (i) {
case PBLOCK_REF: pblock = (IParamBlock*)rtarg; break;
case POINT_REF : base = (Control*)rtarg; break;
}
}
TSTR FExtrudeMod::SubAnimName(int i)
{
switch (i) {
case POINT_REF: return GetString(IDS_RB_EXTRUDECENT);
default: return _T("");
}
}
RefResult FExtrudeMod::NotifyRefChanged(
Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message)
{
switch (message) {
case REFMSG_CHANGE:
if (editMod==this && pmapParam) pmapParam->Invalidate();
break;
case REFMSG_GET_PARAM_DIM: {
GetParamDim *gpd = (GetParamDim*)partID;
switch (gpd->index) {
case PB_AMOUNT: gpd->dim = stdWorldDim; break;
case PB_SCALE: gpd->dim = defaultDim; break;
}
return REF_STOP;
}
case REFMSG_GET_PARAM_NAME: {
GetParamName *gpn = (GetParamName*)partID;
switch (gpn->index) {
case PB_AMOUNT: gpn->name = GetString(IDS_EXT_AMOUNT); break;
case PB_SCALE: gpn->name = GetString(IDS_EXT_SCALE); break;
}
return REF_STOP;
}
}
return REF_SUCCEED;
}
Matrix3 FExtrudeMod::CompMatrix(
TimeValue t,INode *inode,ModContext *mc)
{
Interval iv;
Matrix3 tm(1);
if (mc && mc->tm) tm = Inverse(*(mc->tm));
if (inode) tm = tm * inode->GetObjTMBeforeWSM(t,&iv);
return tm;
}
@@ -0,0 +1,894 @@
/**********************************************************************
*<
FILE: gravity.cpp
DESCRIPTION: Gravity and Wind World Space Modifier
CREATED BY: Rolf Berteig
HISTORY: 10-30-95
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#include "simpmod.h"
#include "simpobj.h"
#include "texutil.h"
#define FORCE_PLANAR 0
#define FORCE_SPHERICAL 1
class ForceObject : public SimpleWSMObject {
public:
static IParamMap *pmapParam;
static IObjParam *ip;
static HWND hSot;
ForceObject() {}
BOOL SupportsDynamics() {return TRUE;}
// From Animatable
void DeleteThis() {delete this;}
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev );
void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next);
// from object
CreateMouseCallBack* GetCreateMouseCallBack();
// From SimpleWSMObject
void InvalidateUI();
void BuildMesh(TimeValue t);
virtual int DialogID()=0;
virtual ParamUIDesc *UIDesc()=0;
virtual int UIDescLength()=0;
};
IObjParam *ForceObject::ip = NULL;
IParamMap *ForceObject::pmapParam = NULL;
HWND ForceObject::hSot = NULL;
class GravityObject : public ForceObject {
public:
GravityObject();
// From Animatable
void DeleteThis() {delete this;}
Class_ID ClassID() {return Class_ID(GRAVITYOBJECT_CLASS_ID,0);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_GRAVITY);}
// From WSMObject
Modifier *CreateWSMMod(INode *node);
ForceField *GetForceField(INode *node);
// From SimpleWSMObject
ParamDimension *GetParameterDim(int pbIndex);
TSTR GetParameterName(int pbIndex);
int DialogID() {return IDD_GRAVITYPARAM;}
ParamUIDesc *UIDesc();
int UIDescLength();
};
class WindObject : public ForceObject {
public:
WindObject();
// From Animatable
void DeleteThis() {delete this;}
Class_ID ClassID() {return Class_ID(WINDOBJECT_CLASS_ID,0);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_WIND);}
// From WSMObject
Modifier *CreateWSMMod(INode *node);
ForceField *GetForceField(INode *node);
// From SimpleWSMObject
ParamDimension *GetParameterDim(int pbIndex);
TSTR GetParameterName(int pbIndex);
int DialogID() {return IDD_WINDPARAM;}
ParamUIDesc *UIDesc();
int UIDescLength();
};
//--- ClassDescriptor and class vars ---------------------------------
class GravityClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE) { return new GravityObject;}
const TCHAR * ClassName() {return GetString(IDS_RB_GRAVITY_CLASS);}
SClass_ID SuperClassID() {return WSM_OBJECT_CLASS_ID; }
Class_ID ClassID() {return Class_ID(GRAVITYOBJECT_CLASS_ID,0);}
const TCHAR* Category() {return GetSpaceWarpCatString(SPACEWARP_CAT_PARTICLE);}
};
static GravityClassDesc gravityDesc;
ClassDesc* GetGravityObjDesc() {return &gravityDesc;}
class WindClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE) { return new WindObject;}
const TCHAR * ClassName() {return GetString(IDS_RB_WIND_CLASS);}
SClass_ID SuperClassID() {return WSM_OBJECT_CLASS_ID; }
Class_ID ClassID() {return Class_ID(WINDOBJECT_CLASS_ID,0);}
const TCHAR* Category() {return GetSpaceWarpCatString(SPACEWARP_CAT_PARTICLE);}
};
static WindClassDesc windDesc;
ClassDesc* GetWindObjDesc() {return &windDesc;}
//--- GravityMod -----------------------------------------------------
class GravityMod;
class GravityField : public ForceField {
public:
GravityObject *obj;
INode *node;
Matrix3 tm;
Interval tmValid;
Point3 force;
Interval fValid;
int type;
Point3 Force(TimeValue t,const Point3 &pos, const Point3 &vel,int index);
};
class GravityMod : public SimpleWSMMod {
public:
GravityField force;
GravityMod() {}
GravityMod(INode *node,GravityObject *obj);
// From Animatable
void GetClassName(TSTR& s) {s= GetString(IDS_RB_GRAVITYMOD);}
SClass_ID SuperClassID() {return WSM_CLASS_ID;}
void DeleteThis() {delete this;}
Class_ID ClassID() { return Class_ID(GRAVITYMOD_CLASS_ID,0);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_GRAVITYBINDING);}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
// From SimpleWSMMod
Interval GetValidity(TimeValue t);
Deformer& GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat);
};
//--- WindMod -----------------------------------------------------
class WindMod;
class WindField : public ForceField {
public:
WindObject *obj;
INode *node;
Matrix3 tm;
Interval tmValid;
Point3 force;
Interval fValid;
int type;
Point3 Force(TimeValue t,const Point3 &pos, const Point3 &vel,int index);
};
class WindMod : public SimpleWSMMod {
public:
WindField force;
WindMod() {}
WindMod(INode *node,WindObject *obj);
// From Animatable
void GetClassName(TSTR& s) {s= GetString(IDS_RB_WINDMOD);}
SClass_ID SuperClassID() {return WSM_CLASS_ID;}
void DeleteThis() {delete this;}
Class_ID ClassID() { return Class_ID(WINDMOD_CLASS_ID,0);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_WINDBINDING);}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
// From SimpleWSMMod
Interval GetValidity(TimeValue t);
Deformer& GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat);
};
//--- ClassDescriptor and class vars ---------------------------------
class GravityModClassDesc:public ClassDesc {
public:
int IsPublic() { return 0; }
void * Create(BOOL loading = FALSE) {return new GravityMod;}
const TCHAR * ClassName() { return GetString(IDS_RB_GRAVITYMOD);}
SClass_ID SuperClassID() {return WSM_CLASS_ID;}
Class_ID ClassID() {return Class_ID(GRAVITYMOD_CLASS_ID,0);}
const TCHAR* Category() {return _T("");}
};
static GravityModClassDesc gravityModDesc;
ClassDesc* GetGravityModDesc() {return &gravityModDesc;}
class WindModClassDesc:public ClassDesc {
public:
int IsPublic() { return 0; }
void * Create(BOOL loading = FALSE) {return new WindMod;}
const TCHAR * ClassName() { return GetString(IDS_RB_WINDMOD);}
SClass_ID SuperClassID() {return WSM_CLASS_ID;}
Class_ID ClassID() {return Class_ID(WINDMOD_CLASS_ID,0);}
const TCHAR* Category() {return _T("");}
};
static WindModClassDesc windModDesc;
ClassDesc* GetWindModDesc() {return &windModDesc;}
//--- GravityObject Parameter map/block descriptors ------------------
#define PB_STRENGTH 0
#define PB_DECAY 1
#define PB_TYPE 2
#define PB_DISPLENGTH 3
//
//
// Parameters
static int typeIDs[] = {IDC_FORCE_PLANAR,IDC_FORCE_SPHERICAL};
static ParamUIDesc descParamGrav[] = {
// Strength
ParamUIDesc(
PB_STRENGTH,
EDITTYPE_FLOAT,
IDC_GRAV_STRENGTH,IDC_GRAV_STRENGTHSPIN,
-9999999.0f, 9999999.0f,
0.01f),
// Decay
ParamUIDesc(
PB_DECAY,
EDITTYPE_FLOAT,
IDC_GRAV_DECAY,IDC_GRAV_DECAYSPIN,
0.0f, 9999999.0f,
0.001f),
// Force type
ParamUIDesc(PB_TYPE,TYPE_RADIO,typeIDs,2),
// Display length
ParamUIDesc(
PB_DISPLENGTH,
EDITTYPE_FLOAT,
IDC_DISPLENGTH,IDC_DISPLENGTHSPIN,
0.0f, 9999999.0f,
SPIN_AUTOSCALE),
};
#define GRAVPARAMDESC_LENGTH 4
ParamBlockDescID descGravVer0[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_INT, NULL, FALSE, 2 },
{ TYPE_FLOAT, NULL, FALSE, 3 }};
#define GRAVPBLOCK_LENGTH 4
#define CURRENT_GRAVVERSION 0
//--- WindObject Parameter map/block descriptors ------------------
#define PB_TURBULENCE 4
#define PB_FREQUENCY 5
#define PB_SCALE 6
//
//
// Parameters
static ParamUIDesc descParamWind[] = {
// Strength
ParamUIDesc(
PB_STRENGTH,
EDITTYPE_FLOAT,
IDC_WIND_STRENGTH,IDC_WIND_STRENGTHSPIN,
-9999999.0f, 9999999.0f,
0.01f),
// Decay
ParamUIDesc(
PB_DECAY,
EDITTYPE_FLOAT,
IDC_WIND_DECAY,IDC_WIND_DECAYSPIN,
0.0f, 9999999.0f,
0.001f),
// Force type
ParamUIDesc(PB_TYPE,TYPE_RADIO,typeIDs,2),
// Turbulence
ParamUIDesc(
PB_TURBULENCE,
EDITTYPE_FLOAT,
IDC_WIND_TURB,IDC_WIND_TURBSPIN,
0.0f, 9999999.0f,
0.01f),
// Frequency
ParamUIDesc(
PB_FREQUENCY,
EDITTYPE_FLOAT,
IDC_WIND_FREQ,IDC_WIND_FREQSPIN,
0.0f, 9999999.0f,
0.01f),
// Scale
ParamUIDesc(
PB_SCALE,
EDITTYPE_FLOAT,
IDC_WIND_SCALE,IDC_WIND_SCALESPIN,
0.0f, 9999999.0f,
0.01f),
// Display length
ParamUIDesc(
PB_DISPLENGTH,
EDITTYPE_FLOAT,
IDC_DISPLENGTH,IDC_DISPLENGTHSPIN,
0.0f, 9999999.0f,
SPIN_AUTOSCALE),
};
#define WINDPARAMDESC_LENGTH 7
ParamBlockDescID descWindVer0[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_INT, NULL, FALSE, 2 },
{ TYPE_FLOAT, NULL, FALSE, 3 },
{ TYPE_FLOAT, NULL, TRUE, 4 },
{ TYPE_FLOAT, NULL, TRUE, 5 },
{ TYPE_FLOAT, NULL, TRUE, 6 }};
#define WINDPBLOCK_LENGTH 7
#define CURRENT_WINDVERSION 0
//--- ForceObject Methods ---------------------------------------------
void ForceObject::BeginEditParams(
IObjParam *ip,ULONG flags,Animatable *prev)
{
SimpleWSMObject::BeginEditParams(ip,flags,prev);
this->ip = ip;
if (pmapParam) {
// Left over from last SinWave ceated
pmapParam->SetParamBlock(pblock);
} else {
hSot = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_WINDGRAV_SOT),
DefaultSOTProc,
GetString(IDS_RB_SOT),
(LPARAM)ip,APPENDROLL_CLOSED);
// Gotta make a new one.
pmapParam = CreateCPParamMap(
UIDesc(),UIDescLength(),
pblock,
ip,
hInstance,
MAKEINTRESOURCE(DialogID()),
GetString(IDS_RB_PARAMETERS),
0);
}
}
void ForceObject::EndEditParams(
IObjParam *ip, ULONG flags,Animatable *next)
{
SimpleWSMObject::EndEditParams(ip,flags,next);
this->ip = NULL;
if (flags&END_EDIT_REMOVEUI ) {
DestroyCPParamMap(pmapParam);
ip->DeleteRollupPage(hSot);
pmapParam = NULL;
}
}
void ForceObject::BuildMesh(TimeValue t)
{
ivalid = FOREVER;
float length;
int type;
pblock->GetValue(PB_DISPLENGTH,t,length,ivalid);
pblock->GetValue(PB_TYPE,t,type,ivalid);
if (type==FORCE_PLANAR) {
mesh.setNumVerts(11);
mesh.setNumFaces(5);
mesh.setVert(0, Point3(-length,-length, 0.0f));
mesh.setVert(1, Point3( length,-length, 0.0f));
mesh.setVert(2, Point3( length, length, 0.0f));
mesh.setVert(3, Point3(-length, length, 0.0f));
mesh.setVert(4, Point3( 0.0f, 0.0f, 0.0f));
mesh.setVert(5, Point3( 0.0f, 0.0f, 3*length));
mesh.setVert(6, Point3( 0.0f, 0.0f, 0.0f));
length *= 0.3f;
mesh.setVert(7, Point3(-length,-length, 7.0f*length));
mesh.setVert(8, Point3( length,-length, 7.0f*length));
mesh.setVert(9, Point3( length, length, 7.0f*length));
mesh.setVert(10, Point3(-length, length, 7.0f*length));
mesh.faces[0].setEdgeVisFlags(1,0,1);
mesh.faces[0].setSmGroup(1);
mesh.faces[0].setVerts(0,1,3);
mesh.faces[1].setEdgeVisFlags(1,1,0);
mesh.faces[1].setSmGroup(1);
mesh.faces[1].setVerts(1,2,3);
mesh.faces[2].setEdgeVisFlags(1,1,0);
mesh.faces[2].setSmGroup(1);
mesh.faces[2].setVerts(4,5,6);
mesh.faces[3].setEdgeVisFlags(0,1,1);
mesh.faces[3].setSmGroup(1);
mesh.faces[3].setVerts(7,9,5);
mesh.faces[4].setEdgeVisFlags(0,1,1);
mesh.faces[4].setSmGroup(1);
mesh.faces[4].setVerts(10,8,5);
} else {
float u;
#define NUM_SEGS 16
mesh.setNumVerts(3*NUM_SEGS+1);
mesh.setNumFaces(3*NUM_SEGS);
for (int i=0; i<NUM_SEGS; i++) {
u = float(i)/float(NUM_SEGS) * TWOPI;
mesh.setVert(i, Point3((float)cos(u) * length, (float)sin(u) * length, 0.0f));
}
for (i=0; i<NUM_SEGS; i++) {
u = float(i)/float(NUM_SEGS) * TWOPI;
mesh.setVert(i+NUM_SEGS, Point3(0.0f, (float)cos(u) * length, (float)sin(u) * length));
}
for (i=0; i<NUM_SEGS; i++) {
u = float(i)/float(NUM_SEGS) * TWOPI;
mesh.setVert(i+2*NUM_SEGS, Point3((float)cos(u) * length, 0.0f, (float)sin(u) * length));
}
mesh.setVert(3*NUM_SEGS, Point3(0.0f, 0.0f, 0.0f));
for (i=0; i<3*NUM_SEGS; i++) {
int i1 = i+1;
if (i1%NUM_SEGS==0) i1 -= NUM_SEGS;
mesh.faces[i].setEdgeVisFlags(1,0,0);
mesh.faces[i].setSmGroup(1);
mesh.faces[i].setVerts(i,i1,3*NUM_SEGS);
}
}
mesh.InvalidateGeomCache();
}
class ForceObjCreateCallback : public CreateMouseCallBack {
public:
ForceObject *ob;
Point3 p0, p1;
IPoint2 sp0;
int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat);
};
int ForceObjCreateCallback::proc(
ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat)
{
if (msg==MOUSE_POINT||msg==MOUSE_MOVE) {
switch(point) {
case 0:
sp0 = m;
p0 = vpt->GetPointOnCP(m);
mat.SetTrans(p0);
break;
case 1:
if (ob->ClassID()==Class_ID(GRAVITYOBJECT_CLASS_ID,0)) {
mat.IdentityMatrix();
mat.RotateX(PI);
mat.SetTrans(p0);
}
p1 = vpt->GetPointOnCP(m);
ob->pblock->SetValue(PB_DISPLENGTH,0,Length(p1-p0)/2.0f);
ob->pmapParam->Invalidate();
if (msg==MOUSE_POINT) {
if (Length(m-sp0)<3) return CREATE_ABORT;
else return CREATE_STOP;
}
break;
}
} else {
if (msg == MOUSE_ABORT)
return CREATE_ABORT;
}
return TRUE;
}
static ForceObjCreateCallback forceCreateCB;
CreateMouseCallBack* ForceObject::GetCreateMouseCallBack()
{
forceCreateCB.ob = this;
return &forceCreateCB;
}
void ForceObject::InvalidateUI()
{
if (pmapParam) pmapParam->Invalidate();
}
//--- GravityObject methods ---------------------------------------
GravityObject::GravityObject()
{
MakeRefByID(FOREVER, 0,
CreateParameterBlock(descGravVer0, GRAVPBLOCK_LENGTH, CURRENT_GRAVVERSION));
assert(pblock);
pblock->SetValue(PB_STRENGTH,0,1.0f);
}
Modifier *GravityObject::CreateWSMMod(INode *node)
{
return new GravityMod(node,this);
}
ForceField *GravityObject::GetForceField(INode *node)
{
GravityField *gf = new GravityField;
gf->obj = this;
gf->node = node;
gf->tmValid.SetEmpty();
gf->fValid.SetEmpty();
gf->obj->pblock->GetValue(PB_TYPE,0,gf->type,FOREVER);
return gf;
}
RefTargetHandle GravityObject::Clone(RemapDir& remap)
{
GravityObject* newob = new GravityObject();
newob->ReplaceReference(0,pblock->Clone(remap));
return newob;
}
ParamDimension *GravityObject::GetParameterDim(int pbIndex)
{
switch (pbIndex) {
case 0:
default: return defaultDim;
}
}
TSTR GravityObject::GetParameterName(int pbIndex)
{
switch (pbIndex) {
case PB_STRENGTH: return GetString(IDS_RB_STRENGTH2);
case PB_DECAY: return GetString(IDS_RB_DECAY);
default: return TSTR(_T(""));
}
}
ParamUIDesc *GravityObject::UIDesc()
{
return descParamGrav;
}
int GravityObject::UIDescLength()
{
return GRAVPARAMDESC_LENGTH;
}
//--- WindObject methods ---------------------------------------
WindObject::WindObject()
{
MakeRefByID(FOREVER, 0,
CreateParameterBlock(descWindVer0, WINDPBLOCK_LENGTH, CURRENT_WINDVERSION));
assert(pblock);
pblock->SetValue(PB_STRENGTH,0,1.0f);
pblock->SetValue(PB_SCALE,0,1.0f);
}
Modifier *WindObject::CreateWSMMod(INode *node)
{
return new WindMod(node,this);
}
ForceField *WindObject::GetForceField(INode *node)
{
WindField *wf = new WindField;
wf->obj = this;
wf->node = node;
wf->tmValid.SetEmpty();
wf->fValid.SetEmpty();
wf->obj->pblock->GetValue(PB_TYPE,0,wf->type,FOREVER);
return wf;
}
RefTargetHandle WindObject::Clone(RemapDir& remap)
{
WindObject* newob = new WindObject();
newob->ReplaceReference(0,pblock->Clone(remap));
return newob;
}
ParamDimension *WindObject::GetParameterDim(int pbIndex)
{
switch (pbIndex) {
case 0:
default: return defaultDim;
}
}
TSTR WindObject::GetParameterName(int pbIndex)
{
switch (pbIndex) {
case PB_STRENGTH: return GetString(IDS_RB_STRENGTH2);
case PB_DECAY: return GetString(IDS_RB_DECAY);
case PB_TURBULENCE: return GetString(IDS_RB_TURBULENCE);
case PB_FREQUENCY: return GetString(IDS_RB_FREQUENCY);
case PB_SCALE: return GetString(IDS_RB_SCALE);
default: return TSTR(_T(""));
}
}
ParamUIDesc *WindObject::UIDesc()
{
return descParamWind;
}
int WindObject::UIDescLength()
{
return WINDPARAMDESC_LENGTH;
}
//--- GravityMod methods -----------------------------------------
GravityMod::GravityMod(INode *node,GravityObject *obj)
{
//MakeRefByID(FOREVER,SIMPWSMMOD_OBREF,obj);
MakeRefByID(FOREVER,SIMPWSMMOD_NODEREF,node);
pblock = NULL;
obRef = NULL;
}
Interval GravityMod::GetValidity(TimeValue t)
{
if (nodeRef) {
Interval valid = FOREVER;
Matrix3 tm;
float f;
((GravityObject*)GetWSMObject(t))->pblock->GetValue(PB_STRENGTH,t,f,valid);
tm = nodeRef->GetObjectTM(t,&valid);
return valid;
} else {
return FOREVER;
}
}
class GravityDeformer : public Deformer {
public:
Point3 Map(int i, Point3 p) {return p;}
};
static GravityDeformer gdeformer;
Deformer& GravityMod::GetDeformer(
TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
{
return gdeformer;
}
RefTargetHandle GravityMod::Clone(RemapDir& remap)
{
GravityMod *newob = new GravityMod(nodeRef,(GravityObject*)obRef);
newob->SimpleWSMModClone(this);
return newob;
}
void GravityMod::ModifyObject(
TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
ParticleObject *obj = GetParticleInterface(os->obj);
if (obj) {
force.obj = (GravityObject*)GetWSMObject(t);
force.node = nodeRef;
force.tmValid.SetEmpty();
force.fValid.SetEmpty();
force.obj->pblock->GetValue(PB_TYPE,t,force.type,FOREVER);
obj->ApplyForceField(&force);
}
}
// This is an adjustment to forces to make the independent of time scale.
// They were previously dependent on the old 1200 ticks per second constant.
// Note that the constants are being squared because we are dealing with acceleration not velocity.
static float forceScaleFactor = float(1200*1200)/float(TIME_TICKSPERSEC*TIME_TICKSPERSEC);
Point3 GravityField::Force(
TimeValue t,const Point3 &pos, const Point3 &vel,int index)
{
float strength, decay;
obj->pblock->GetValue(PB_DECAY,t,decay,fValid);
if (decay <0.0f) decay = 0.0f;
if (!fValid.InInterval(t) || type==FORCE_SPHERICAL || decay!=0.0f) {
fValid = FOREVER;
if (!tmValid.InInterval(t)) {
tmValid = FOREVER;
tm = node->GetObjectTM(t,&tmValid);
}
fValid &= tmValid;
obj->pblock->GetValue(PB_STRENGTH,t,strength,fValid);
if (type==FORCE_PLANAR) {
force = Normalize(tm.GetRow(2));
if (decay!=0.0f) {
float dist = DotProd(force,pos-tm.GetTrans());
strength *= (float)exp(-decay*dist);
}
force *= strength * 0.0001f * forceScaleFactor;
} else {
float dist;
force = tm.GetTrans()-pos;
dist = Length(force);
if (dist!=0.0f) force /= dist;
if (decay!=0.0f) {
strength *= (float)exp(-decay*dist);
}
force *= strength * 0.0001f * forceScaleFactor;
}
}
return force;
}
//--- WindMod methods -----------------------------------------
WindMod::WindMod(INode *node,WindObject *obj)
{
//MakeRefByID(FOREVER,SIMPWSMMOD_OBREF,obj);
MakeRefByID(FOREVER,SIMPWSMMOD_NODEREF,node);
pblock = NULL;
obRef = NULL;
}
Interval WindMod::GetValidity(TimeValue t)
{
if (nodeRef) {
Interval valid = FOREVER;
Matrix3 tm;
float f;
((WindObject*)GetWSMObject(t))->pblock->GetValue(PB_STRENGTH,t,f,valid);
tm = nodeRef->GetObjectTM(t,&valid);
return valid;
} else {
return FOREVER;
}
}
class WindDeformer : public Deformer {
public:
Point3 Map(int i, Point3 p) {return p;}
};
static WindDeformer wdeformer;
Deformer& WindMod::GetDeformer(
TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
{
return wdeformer;
}
RefTargetHandle WindMod::Clone(RemapDir& remap)
{
WindMod *newob = new WindMod(nodeRef,(WindObject*)obRef);
newob->SimpleWSMModClone(this);
return newob;
}
void WindMod::ModifyObject(
TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
ParticleObject *obj = GetParticleInterface(os->obj);
if (obj) {
force.obj = (WindObject*)GetWSMObject(t);
force.node = nodeRef;
force.tmValid.SetEmpty();
force.fValid.SetEmpty();
force.obj->pblock->GetValue(PB_TYPE,t,force.type,FOREVER);
obj->ApplyForceField(&force);
}
}
static float RTurbulence(Point3 p,float freq)
{
return noise3(p*freq);
}
Point3 WindField::Force(
TimeValue t,const Point3 &pos, const Point3 &vel,int index)
{
float strength, decay, turb;
obj->pblock->GetValue(PB_DECAY,t,decay,fValid);
obj->pblock->GetValue(PB_TURBULENCE,t,turb,FOREVER);
if (decay <0.0f) decay = 0.0f;
if (!fValid.InInterval(t) || type==FORCE_SPHERICAL || decay!=0.0f) {
fValid = FOREVER;
if (!tmValid.InInterval(t)) {
tmValid = FOREVER;
tm = node->GetObjectTM(t,&tmValid);
}
fValid &= tmValid;
obj->pblock->GetValue(PB_STRENGTH,t,strength,fValid);
if (type==FORCE_PLANAR) {
force = Normalize(tm.GetRow(2));
if (decay!=0.0f) {
float dist = (float)fabs(DotProd(force,pos-tm.GetTrans()));
strength *= (float)exp(-decay*dist);
}
force *= strength * 0.0001f * forceScaleFactor;
} else {
float dist;
force = pos-tm.GetTrans();
dist = Length(force);
if (dist!=0.0f) force /= dist;
if (decay!=0.0f) {
strength *= (float)exp(-decay*dist);
}
force *= strength * 0.0001f * forceScaleFactor;
}
}
if (turb!=0.0f) {
float freq, scale;
Point3 tf, pt = pos-tm.GetTrans(), p;
obj->pblock->GetValue(PB_FREQUENCY,t,freq,FOREVER);
obj->pblock->GetValue(PB_SCALE,t,scale,FOREVER);
freq *= 0.01f;
turb *= 0.0001f * forceScaleFactor;
p = pt;
p.x = freq * float(t);
tf.x = RTurbulence(p,scale);
p = pt;
p.y = freq * float(t);
tf.y = RTurbulence(p,scale);
p = pt;
p.z = freq * float(t);
tf.z = RTurbulence(p,scale);
return force + (turb*tf);
} else {
return force;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,175 @@
/**********************************************************************
*<
FILE: mapping.h
DESCRIPTION:
CREATED BY: Rolf Berteig
HISTORY: 10/21/95
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#ifndef __MAPPING__
#define __MAPPING__
class MappingMod : public Modifier {
public:
DWORD flags;
float aspect;
Control *tmControl;
static IObjParam *ip;
void* GetInterface(ULONG id);
void InitControl(ModContext &mc,Object *obj,int type,TimeValue t);
void Move(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE);
void Rotate(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Quat& val, BOOL localOrigin=FALSE);
void Scale(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE);
Matrix3 CompMatrix(TimeValue t,ModContext *mc, Matrix3 *ntm,BOOL applySize=TRUE, BOOL applyAxis=TRUE);
void DoIcon(PolyLineProc& lp,BOOL sel);
int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc);
int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags, ModContext *mc);
void GetWorldBoundBox(TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc);
void GetSubObjectCenters(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void GetSubObjectTMs(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void ViewportAlign();
virtual void EnterNormalAlign()=0;
virtual void ExitNormalAlign()=0;
virtual void EnterRegionFit()=0;
virtual void ExitRegionFit()=0;
virtual int GetMapType()=0;
virtual void SetMapType(int type)=0;
virtual float GetTile(TimeValue t,int which)=0;
virtual void SetTile(TimeValue t,int which, float tile)=0;
virtual BOOL GetFlip(int which)=0;
virtual void SetFlip(int which,BOOL flip)=0;
virtual float GetLength(TimeValue t)=0;
virtual float GetWidth(TimeValue t)=0;
virtual float GetHeight(TimeValue t)=0;
virtual int GetAxis()=0;
virtual void SetLength(TimeValue t,float v)=0;
virtual void SetWidth(TimeValue t,float v)=0;
virtual void SetHeight(TimeValue t,float v)=0;
virtual void SetAxis(int v)=0;
virtual int GetFirstParamVer()=0;
virtual int GetPBlockVersion()=0;
virtual void EnterAcquire()=0;
virtual void ExitAcquire()=0;
};
#define I_MAPPINGINTERFACE 0x9836d7f1
#define GetMappingInterface(anim) ((MappingMod*)anim->GetInterface(I_MAPPINGINTERFACE))
#define TM_REF 0
#define PBLOCK_REF 1
// Flags
#define CONTROL_FIT (1<<0)
#define CONTROL_CENTER (1<<1)
#define CONTROL_ASPECT (1<<2)
#define CONTROL_UNIFORM (1<<3)
#define CONTROL_HOLD (1<<4)
#define CONTROL_INIT (1<<5)
#define CONTROL_OP (CONTROL_FIT|CONTROL_CENTER|CONTROL_ASPECT|CONTROL_UNIFORM)
#define CONTROL_INITPARAMS (1<<10)
#define CID_FACEALIGNMAP 0x4f298c7a
#define CID_REGIONFIT 0x4f298c7b
class FaceAlignMouseProc : public MouseCallBack {
public:
MappingMod *mod;
IObjParam *ip;
FaceAlignMouseProc(MappingMod *m,IObjParam *i) {mod=m;ip=i;}
int proc(HWND hWnd, int msg, int point, int flags, IPoint2 m);
void FaceAlignMap(HWND hWnd,IPoint2 m);
};
class FaceAlignMode : public CommandMode {
public:
ChangeFGObject fgProc;
FaceAlignMouseProc proc;
IObjParam *ip;
MappingMod *mod;
FaceAlignMode(MappingMod *m,IObjParam *i)
: fgProc(m), proc(m,i) {ip=i;mod=m;}
int Class() {return MOVE_COMMAND;}
int ID() {return CID_FACEALIGNMAP;}
MouseCallBack *MouseProc(int *numPoints) {*numPoints=2;return &proc;}
ChangeForegroundCallback *ChangeFGProc() {return &fgProc;}
BOOL ChangeFG(CommandMode *oldMode) {return oldMode->ChangeFGProc() != &fgProc;}
void EnterMode();
void ExitMode();
};
class RegionFitMouseProc : public MouseCallBack {
public:
MappingMod *mod;
IObjParam *ip;
IPoint2 om;
RegionFitMouseProc(MappingMod *m,IObjParam *i) {mod=m;ip=i;}
int proc(HWND hWnd, int msg, int point, int flags, IPoint2 m);
void RegionFitMap(HWND hWnd,IPoint2 m);
};
class RegionFitMode : public CommandMode {
public:
ChangeFGObject fgProc;
RegionFitMouseProc proc;
IObjParam *ip;
MappingMod *mod;
RegionFitMode(MappingMod *m,IObjParam *i)
: fgProc(m), proc(m,i) {ip=i;mod=m;}
int Class() {return MOVE_COMMAND;}
int ID() {return CID_REGIONFIT;}
MouseCallBack *MouseProc(int *numPoints) {*numPoints=2;return &proc;}
ChangeForegroundCallback *ChangeFGProc() {return &fgProc;}
BOOL ChangeFG(CommandMode *oldMode) {return oldMode->ChangeFGProc() != &fgProc;}
void EnterMode();
void ExitMode();
};
class PickAcquire :
public PickModeCallback,
public PickNodeCallback {
public:
MappingMod *mod;
IObjParam *ip;
PickAcquire() {mod = NULL; ip = NULL;}
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);
MappingMod *FindFirstMap(ReferenceTarget *ref);
void AcquireMapping(
MappingMod *toMod, ModContext *toMC, INode *toNode,
MappingMod *fromMod, ModContext *fromMC, INode *fromNode,
int type);
};
class FixDimsPLCB : public PostLoadCallback {
public:
MappingMod *mod;
FixDimsPLCB(MappingMod *m) {mod=m;}
void proc(ILoad *iload);
};
#endif //__MAPPING__
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,675 @@
/**********************************************************************
*<
FILE: mirror.cpp
DESCRIPTION: Mirror modifier
CREATED BY: Rolf Berteig
HISTORY: 12/06/96
*> Copyright (c) 1996, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#include "splshape.h"
#define TM_REF 0
#define PBLOCK_REF 1
#define MIRRORMOD_CLASS_ID Class_ID(0xef92aa7c,0x511bbe75);
class MirrorMod : public Modifier {
public:
IParamBlock *pblock;
Control *tmControl;
Control *p1, *p2;
BYTE sel[2];
static IObjParam *ip;
static IParamMap *pmapParam;
static MirrorMod *editMod;
static MoveModBoxCMode *moveMode;
static RotateModBoxCMode *rotMode;
static UScaleModBoxCMode *uscaleMode;
static NUScaleModBoxCMode *nuscaleMode;
static SquashModBoxCMode *squashMode;
MirrorMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) {s = GetString(IDS_RB_MIRRORMOD);}
virtual Class_ID ClassID() {return MIRRORMOD_CLASS_ID;}
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip,ULONG flags,Animatable *next);
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_MIRRORMOD);}
BOOL AssignController(Animatable *control,int subAnim);
int SubNumToRefNum(int subNum);
// From modifier
ChannelMask ChannelsUsed() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_SUBSEL_TYPE;}
ChannelMask ChannelsChanged() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_TEXMAP;}
Class_ID InputType() {return defObjectClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t);
// From BaseObject
int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc);
int Display(TimeValue t, INode* inode, ViewExp *vpt, int flagst, ModContext *mc);
void GetWorldBoundBox(TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc);
void Move(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin);
void Rotate(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Quat& val, BOOL localOrigin);
void Scale(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin);
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
void GetSubObjectCenters(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void GetSubObjectTMs(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc);
void ActivateSubobjSel(int level, XFormModes& modes);
int NumRefs() {return 2;}
RefTargetHandle GetReference(int i);
void SetReference(int i, RefTargetHandle rtarg);
int NumSubs() {return 2;}
Animatable* SubAnim(int i) {return GetReference(i);}
TSTR SubAnimName(int i);
RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message);
Matrix3 CompMatrix(TimeValue t,INode *inode,ModContext *mc);
void DrawGizmo(float size,PolyLineProc& lp);
};
class MirrorDeformer : public Deformer {
public:
Matrix3 tm, itm;
MirrorDeformer(int axis, float offset, Matrix3 &tm, Matrix3 &itm);
Point3 Map(int i, Point3 p) {return (tm*p)*itm;}
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *MirrorMod::pmapParam = NULL;
IObjParam *MirrorMod::ip = NULL;
MirrorMod *MirrorMod::editMod = NULL;
MoveModBoxCMode *MirrorMod::moveMode = NULL;
RotateModBoxCMode *MirrorMod::rotMode = NULL;
UScaleModBoxCMode *MirrorMod::uscaleMode = NULL;
NUScaleModBoxCMode *MirrorMod::nuscaleMode = NULL;
SquashModBoxCMode *MirrorMod::squashMode = NULL;
class MirrorModClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE) {return new MirrorMod;}
const TCHAR * ClassName() { return GetString(IDS_RB_MIRRORMOD); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return MIRRORMOD_CLASS_ID;}
const TCHAR* Category() { return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static MirrorModClassDesc mirrorDesc;
extern ClassDesc* GetMirrorModDesc() {return &mirrorDesc;}
//--- Parameter map/block descriptors -------------------------------
#define PB_AXIS 0
#define PB_COPY 1
#define PB_OFFSET 2
//
//
// Parameters
static int axisIDs[] = {IDS_MIRROR_X,IDS_MIRROR_Y,IDS_MIRROR_Z,IDS_MIRROR_XY,IDS_MIRROR_YZ,IDS_MIRROR_ZX};
static ParamUIDesc descParam[] = {
// Axis
ParamUIDesc(PB_AXIS,TYPE_RADIO,axisIDs,6),
// Copy
ParamUIDesc(PB_COPY,TYPE_SINGLECHEKBOX,IDC_MIRROR_COPY),
// Offset
ParamUIDesc(
PB_OFFSET,
EDITTYPE_UNIVERSE,
IDC_MIRROR_OFFSET,IDC_MIRROR_OFFSETSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
};
#define PARAMDESC_LENGTH 3
static ParamBlockDescID descVer0[] = {
{ TYPE_INT, NULL, FALSE, 0 }, // Axis
{ TYPE_INT, NULL, FALSE, 1 }, // Copy
{ TYPE_FLOAT, NULL, TRUE, 2 }, // Offset
};
#define PBLOCK_LENGTH 3
#define CURRENT_VERSION 0
//--- Affect region mod methods -------------------------------
MirrorMod::MirrorMod()
{
tmControl = NULL;
pblock = NULL;
MakeRefByID(
FOREVER, PBLOCK_REF,
CreateParameterBlock(
descVer0, PBLOCK_LENGTH, CURRENT_VERSION));
MakeRefByID(FOREVER,TM_REF,NewDefaultMatrix3Controller());
}
void MirrorMod::BeginEditParams(
IObjParam *ip, ULONG flags,Animatable *prev)
{
this->ip = ip;
editMod = this;
// Add our sub object type
TSTR type1(GetString(IDS_RB_MIRRORCENTER));
const TCHAR *ptype[] = {type1};
ip->RegisterSubObjectTypes(ptype, 1);
// Create sub object editing modes.
moveMode = new MoveModBoxCMode(this,ip);
rotMode = new RotateModBoxCMode(this,ip);
uscaleMode = new UScaleModBoxCMode(this,ip);
nuscaleMode = new NUScaleModBoxCMode(this,ip);
squashMode = new SquashModBoxCMode(this,ip);
TimeValue t = ip->GetTime();
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_BEGIN_EDIT);
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_MOD_DISPLAY_ON);
SetAFlag(A_MOD_BEING_EDITED);
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGTH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_MIRRORPARAM),
GetString(IDS_RB_PARAMETERS),
0);
}
void MirrorMod::EndEditParams(
IObjParam *ip,ULONG flags,Animatable *next)
{
this->ip = NULL;
editMod = NULL;
TimeValue t = ip->GetTime();
// NOTE: This flag must be cleared before sending the REFMSG_END_EDIT
ClearAFlag(A_MOD_BEING_EDITED);
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_END_EDIT);
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_MOD_DISPLAY_OFF);
ip->DeleteMode(moveMode);
ip->DeleteMode(rotMode);
ip->DeleteMode(uscaleMode);
ip->DeleteMode(nuscaleMode);
ip->DeleteMode(squashMode);
if ( moveMode ) delete moveMode;
moveMode = NULL;
if ( rotMode ) delete rotMode;
rotMode = NULL;
if ( uscaleMode ) delete uscaleMode;
uscaleMode = NULL;
if ( nuscaleMode ) delete nuscaleMode;
nuscaleMode = NULL;
if ( squashMode ) delete squashMode;
squashMode = NULL;
DestroyCPParamMap(pmapParam);
}
RefTargetHandle MirrorMod::Clone(RemapDir& remap)
{
MirrorMod *mod = new MirrorMod();
mod->ReplaceReference(PBLOCK_REF,pblock->Clone(remap));
mod->ReplaceReference(TM_REF,remap.CloneRef(tmControl));
return mod;
}
MirrorDeformer::MirrorDeformer(
int axis, float offset, Matrix3 &tm, Matrix3 &itm)
{
this->tm = tm;
this->itm = itm;
Point3 scale(1,1,1), off(0,0,0);
switch (axis) {
case 0:
case 1:
case 2:
scale[axis] = -1.0f;
off[axis] = offset;
break;
case 3:
case 4:
case 5:
scale[(axis)%3] = -1.0f;
scale[(axis+1)%3] = -1.0f;
off[(axis)%3] = offset;
off[(axis+1)%3] = offset;
break;
}
this->tm.Scale(scale,TRUE);
this->tm.Translate(off);
}
void MirrorMod::ModifyObject(
TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
Matrix3 itm = CompMatrix(t,NULL,&mc);
Matrix3 tm = Inverse(itm);
Interval iv = FOREVER;
int axis, copy;
float offset;
pblock->GetValue(PB_AXIS,t,axis,iv);
pblock->GetValue(PB_COPY,t,copy,iv);
pblock->GetValue(PB_OFFSET,t,offset,iv);
DWORD oldLevel;
BOOL convertedShape = FALSE;
if (os->obj->IsSubClassOf(triObjectClassID)) {
TriObject *tobj = (TriObject*)os->obj;
Mesh &mesh = tobj->mesh;
switch (mesh.selLevel) {
case MESH_OBJECT: mesh.faceSel.SetAll(); break;
case MESH_VERTEX: {
for (int i=0; i<mesh.getNumFaces(); i++) {
for (int j=0; j<3; j++) {
if (mesh.vertSel[mesh.faces[i].v[j]]) {
mesh.faceSel.Set(i);
}
}
}
break;
}
case MESH_EDGE: {
for (int i=0; i<mesh.getNumFaces(); i++) {
for (int j=0; j<3; j++) {
if (mesh.edgeSel[i*3+j]) {
mesh.faceSel.Set(i);
}
}
}
break;
}
}
oldLevel = mesh.selLevel;
mesh.selLevel = MESH_FACE;
if (copy) mesh.CloneFaces(mesh.faceSel);
if (axis<3) {
for (int i=0; i<mesh.getNumFaces(); i++) {
if (mesh.faceSel[i]) mesh.FlipNormal(i);
}
}
}
else
if (os->obj->IsSubClassOf(splineShapeClassID)) {
SplineShape *ss = (SplineShape*)os->obj;
BezierShape &shape = ss->shape;
oldLevel = shape.selLevel;
switch (shape.selLevel) {
case SHAPE_OBJECT:
case SHAPE_VERTEX:
shape.selLevel = SHAPE_SPLINE;
shape.polySel.SetAll();
break;
case SHAPE_SPLINE:
case SHAPE_SEGMENT:
break;
}
if (copy)
shape.CloneSelectedParts((axis < 3) ? TRUE : FALSE);
}
else
if(os->obj->SuperClassID() == SHAPE_CLASS_ID) {
ShapeObject *so = (ShapeObject *)os->obj;
if(so->CanMakeBezier()) {
SplineShape *ss = new SplineShape();
so->MakeBezier(t, ss->shape);
ss->SetChannelValidity(GEOM_CHAN_NUM, LocalValidity(t) & so->ObjectValidity(t));
os->obj = ss;
os->obj->UnlockObject();
convertedShape = TRUE;
BezierShape &shape = ss->shape;
oldLevel = shape.selLevel;
switch (shape.selLevel) {
case SHAPE_OBJECT:
case SHAPE_VERTEX:
shape.selLevel = SHAPE_SPLINE;
shape.polySel.SetAll();
break;
case SHAPE_SPLINE:
case SHAPE_SEGMENT:
break;
}
if (copy)
shape.CloneSelectedParts((axis < 3) ? TRUE : FALSE);
}
}
MirrorDeformer deformer(axis,offset,tm,itm);
os->obj->Deform(&deformer, TRUE);
os->obj->UpdateValidity(GEOM_CHAN_NUM,LocalValidity(t));
if (os->obj->IsSubClassOf(triObjectClassID)) {
TriObject *tobj = (TriObject*)os->obj;
tobj->mesh.selLevel = oldLevel;
}
else
if(os->obj->IsSubClassOf(splineShapeClassID) || convertedShape) {
SplineShape *ss = (SplineShape*)os->obj;
ss->shape.selLevel = oldLevel;
}
}
Interval MirrorMod::LocalValidity(TimeValue t)
{
Interval iv = FOREVER;
Matrix3 mat(1);
tmControl->GetValue(t,&mat,iv,CTRL_RELATIVE);
float o;
pblock->GetValue(PB_OFFSET,t,o,iv);
return iv;
}
Matrix3 MirrorMod::CompMatrix(
TimeValue t,INode *inode,ModContext *mc)
{
Interval iv;
Matrix3 tm(1);
tmControl->GetValue(t,&tm,iv,CTRL_RELATIVE);
if (mc && mc->tm) tm = tm * Inverse(*(mc->tm));
if (inode) tm = tm * inode->GetObjTMBeforeWSM(t,&iv);
return tm;
}
#define AXIS_SIZE 2.0f
#define SCREEN_SCALE 0.1f
static void SetupAxisPoints(
Point3 &v, Point3 &vp, float size,Point3 *pts)
{
pts[0] = (vp)*size;
pts[2] = (-vp)*size;
pts[1] = (v^vp)*size;
pts[3] = (v^(-vp))*size;
pts[4] = pts[0];
pts[5] = -v*size*AXIS_SIZE;
pts[6] = v*size*AXIS_SIZE;
Point3 v2 = v*0.9f*size*AXIS_SIZE;
pts[7] = v2+pts[0]*0.1f;
pts[8] = pts[6];
pts[9] = v2+pts[2]*0.1f;
pts[10] = v2+pts[1]*0.1f;
pts[11] = pts[6];
pts[12] = v2+pts[3]*0.1f;
pts[13] = -v2+pts[0]*0.1f;
pts[14] = -pts[6];
pts[15] = -v2+pts[2]*0.1f;
pts[16] = -v2+pts[1]*0.1f;
pts[17] = -pts[6];
pts[18] = -v2+pts[3]*0.1f;
}
void MirrorMod::DrawGizmo(float size,PolyLineProc& lp)
{
Point3 v0(0,0,0), pv0(0,0,0), v1(0,0,0), pv1(0,0,0);
int ct=0;
int axis;
pblock->GetValue(PB_AXIS,0,axis,FOREVER);
switch (axis) {
case 0:
case 1:
case 2:
v0[axis] = -1.0f;
pv0[(axis+1)%3] = 1.0f;
pv0[(axis+2)%3] = 1.0f;
ct=1;
break;
case 3:
case 4:
case 5:
v0[(axis)%3] = -1.0f;
pv0[(axis+1)%3] = 1.0f;
pv0[(axis+2)%3] = 1.0f;
v1[(axis+1)%3] = -1.0f;
pv1[(axis+2)%3] = 1.0f;
pv1[(axis+3)%3] = 1.0f;
ct=2;
break;
}
Point3 pts[20];
SetupAxisPoints(v0, pv0, size, pts);
lp.proc(pts,5);
lp.proc(pts+5,2);
lp.proc(pts+7,3);
lp.proc(pts+10,3);
lp.proc(pts+13,3);
lp.proc(pts+16,3);
if (ct==2) {
SetupAxisPoints(v1, pv1, size, pts);
lp.proc(pts,5);
lp.proc(pts+5,2);
lp.proc(pts+7,3);
lp.proc(pts+10,3);
lp.proc(pts+13,3);
lp.proc(pts+16,3);
}
}
int MirrorMod::HitTest(
TimeValue t, INode* inode,
int type, int crossing, int flags,
IPoint2 *p, ViewExp *vpt, ModContext* mc)
{
GraphicsWindow *gw = vpt->getGW();
Point3 pt;
HitRegion hr;
int savedLimits, res = 0;
Matrix3 tm = CompMatrix(t,inode,mc);
MakeHitRegion(hr,type, crossing,4,p);
gw->setHitRegion(&hr);
gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM);
gw->setTransform(tm);
gw->clearHitCode();
DrawLineProc lp(gw);
DrawGizmo(
vpt->GetScreenScaleFactor(tm.GetTrans())*SCREEN_SCALE,lp);
gw->setRndLimits(savedLimits);
if (gw->checkHitCode()) {
vpt->LogHit(inode, mc, gw->getHitDistance(), 0, NULL);
return 1;
}
return 0;
}
int MirrorMod::Display(
TimeValue t, INode* inode, ViewExp *vpt,
int flagst, ModContext *mc)
{
GraphicsWindow *gw = vpt->getGW();
Point3 pt[4];
Matrix3 tm = CompMatrix(t,inode,mc);
int savedLimits;
gw->setRndLimits((savedLimits = gw->getRndLimits()) & ~GW_ILLUM);
gw->setTransform(tm);
if (ip && ip->GetSubObjectLevel() == 1) {
//gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
} else {
//gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0);
gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS));
}
DrawLineProc lp(gw);
DrawGizmo(
vpt->GetScreenScaleFactor(tm.GetTrans())*SCREEN_SCALE,lp);
gw->setRndLimits(savedLimits);
return 0;
}
void MirrorMod::GetWorldBoundBox(
TimeValue t,INode* inode, ViewExp *vpt,
Box3& box, ModContext *mc)
{
GraphicsWindow *gw = vpt->getGW();
Matrix3 tm = CompMatrix(t,inode,mc);
BoxLineProc bproc(&tm);
DrawGizmo(
vpt->GetScreenScaleFactor(tm.GetTrans())*SCREEN_SCALE,bproc);
box = bproc.Box();
}
void MirrorMod::Move(TimeValue t, Matrix3& partm, Matrix3& tmAxis,
Point3& val, BOOL localOrigin)
{
SetXFormPacket pckt(val,partm,tmAxis);
tmControl->SetValue(t,&pckt,TRUE,CTRL_RELATIVE);
}
void MirrorMod::Rotate(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Quat& val, BOOL localOrigin)
{
SetXFormPacket pckt(val,localOrigin,partm,tmAxis);
tmControl->SetValue(t,&pckt,TRUE,CTRL_RELATIVE);
}
void MirrorMod::Scale(TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin)
{
SetXFormPacket pckt(val,localOrigin,partm,tmAxis);
tmControl->SetValue(t,&pckt,TRUE,CTRL_RELATIVE);
}
void MirrorMod::GetSubObjectCenters(
SubObjAxisCallback *cb,TimeValue t,
INode *node,ModContext *mc)
{
Matrix3 tm = CompMatrix(t,node,mc);
cb->Center(tm.GetTrans(),0);
}
void MirrorMod::GetSubObjectTMs(
SubObjAxisCallback *cb,TimeValue t,
INode *node,ModContext *mc)
{
Matrix3 tm = CompMatrix(t,node,mc);
cb->TM(tm,0);
}
void MirrorMod::ActivateSubobjSel(int level, XFormModes& modes)
{
switch (level) {
case 1: // Mirror center
modes = XFormModes(moveMode,rotMode,nuscaleMode,uscaleMode,squashMode,NULL);
break;
}
NotifyDependents(FOREVER,PART_DISPLAY,REFMSG_CHANGE);
}
BOOL MirrorMod::AssignController(Animatable *control,int subAnim)
{
if (subAnim==TM_REF) {
ReplaceReference(TM_REF,(ReferenceTarget*)control);
NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
NotifyDependents(FOREVER,PART_ALL,REFMSG_SUBANIM_STRUCTURE_CHANGED);
return TRUE;
} else {
return FALSE;
}
}
int MirrorMod::SubNumToRefNum(int subNum)
{
if (subNum==TM_REF) return subNum;
else return -1;
}
RefTargetHandle MirrorMod::GetReference(int i)
{
switch (i) {
case PBLOCK_REF: return pblock;
case TM_REF: return tmControl;
default: return NULL;
}
}
void MirrorMod::SetReference(int i, RefTargetHandle rtarg)
{
switch (i) {
case PBLOCK_REF: pblock = (IParamBlock*)rtarg; break;
case TM_REF: tmControl = (Control*)rtarg; break;
}
}
TSTR MirrorMod::SubAnimName(int i)
{
switch (i) {
case TM_REF: return GetString(IDS_RB_MIRRORCENTER); break;
default: return _T(""); break;
}
}
RefResult MirrorMod::NotifyRefChanged(
Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message)
{
switch (message) {
case REFMSG_CHANGE:
if (editMod==this && pmapParam) pmapParam->Invalidate();
break;
case REFMSG_GET_PARAM_DIM: {
GetParamDim *gpd = (GetParamDim*)partID;
switch (gpd->index) {
case PB_OFFSET: gpd->dim = stdWorldDim; break;
}
return REF_STOP;
}
case REFMSG_GET_PARAM_NAME: {
GetParamName *gpn = (GetParamName*)partID;
switch (gpn->index) {
case PB_OFFSET: gpn->name = GetString(IDS_RB_OFFSET); break;
}
return REF_STOP;
}
}
return REF_SUCCEED;
}
@@ -0,0 +1,8 @@
LIBRARY mods
EXPORTS
LibDescription @1
LibNumberClasses @2
LibClassDesc @3
LibVersion @4
SECTIONS
.data READ WRITE
@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 5.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "mods"=.\Mods.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,979 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by mods.rc
//
#define IDD_BENDPARAM 101
#define IDC_TH_SELCURSOR 101
#define IDD_TAPERPARAM 102
#define IDC_EXTRUDECUR 102
#define IDD_SINWAVEPARAM 103
#define IDD_SINWAVEPARAM1 103
#define IDB_FACESELTYPES 103
#define IDC_CLOSECUR 103
#define IDC_OUTLINECUR 103
#define IDD_SINWAVEPARAM2 104
#define IDB_MASK_FACESELTYPES 104
#define IDC_SEGBREAKCUR 104
#define IDD_SINWAVEMODPARAM 105
#define IDC_SEGREFINECUR 105
#define IDD_EDITMESHPARAM 106
#define IDD_EMPARAM_VERTEX 106
#define IDC_VERTCONNECTCUR 106
#define IDD_EMPARAM_FACE 107
#define IDC_VERTINSERTCUR 107
#define IDD_EMPARAM_EDGE 108
#define IDD_DETACH 109
#define IDB_BOOLEANTYPES 110
#define IDD_EMPARAM_OBJECT 111
#define IDB_MASK_BOOLEANTYPES 111
#define IDD_ESPARAM_VERTEX 112
#define IDD_ESPARAM_OBJECT 113
#define IDD_ESPARAM_SEGMENT 114
#define IDD_ESPARAM_SPLINE 115
#define IDD_AUTHMSG 116
#define IDD_AUTHORIZE 117
#define IDB_MASK_BULBS 117
#define IDD_TWISTPARAM 118
#define IDB_BULBS 118
#define IDD_ESPARAM_POLYGON 119
#define IDC_ADDVERTCUR 119
#define IDB_MASK_MIRRORTYPES 119
#define IDD_EXTRUDEPARAM 120
#define IDB_MIRRORTYPES 120
#define IDD_EPPARAM_VERTEX 121
#define IDD_EPPARAM_PATCH 122
#define IDD_EPPARAM_OBJECT 123
#define IDD_BOMBPARAMS 124
#define IDD_ELPARAM_OBJECT 125
#define IDD_ELPARAM_PATH 126
#define IDD_ELPARAM_SECTION 127
#define IDD_AFFECTREGION 128
#define IDD_SKEWPARAM 129
#define IDD_NOISEPARAM 130
#define IDD_SINWAVEOMODPARAM 131
#define IDD_LINWAVEPARAM1 132
#define IDD_LINWAVEOMODPARAM 133
#define IDD_OPTIMIZEPARAM 134
#define IDD_DISPLACEPARAM 135
#define IDD_CLUSTNODEPARAM 136
#define IDD_EM_SELECTBYMAT 137
#define IDD_WINDPARAM 138
#define IDD_GRAVITYPARAM 139
#define IDD_DEFLECTORPARAM 140
#define IDD_UVWMAPPARAM 141
#define IDD_EMPARAM_SURFACE 142
#define IDD_EM_SELECTBYSMOOTH 143
#define IDD_DISPLACE_SOT 144
#define IDD_WINDRAIN_SOT 145
#define IDD_SINWAVE_SOT 146
#define IDD_BOMB_SOT 147
#define IDD_SELECTPARAM 148
#define IDD_MATERIALPARAM 149
#define IDD_SMOOTHPARAM 150
#define IDD_NORMALPARAM 151
#define IDD_SURFREVPARAM 152
#define IDD_EPPARAM_EDGE 153
#define IDD_DISPLACEPARAM_WS 154
#define IDD_UNWRAP_FLOATER 155
#define IDB_UNWRAPTOOL 156
#define IDB_MASK_UNWRAPTOOL 157
#define IDD_UNWRAP_PROP 157
#define IDD_MAP_ACQUIRE 201
#define IDD_RESETXFORM_PANEL 202
#define IDD_AFRPARAM 203
#define IDD_TESSPARAM 204
#define IDD_MESHSEL_FACE 205
#define IDD_MESHSEL_VERTEX 206
#define IDD_MESHSEL_EDGE 207
#define IDD_MESHSEL_OBJECT 208
#define IDD_FACEEXTRUDEPARAM 209
#define IDD_UVWXFORMPARAM 210
#define IDD_MIRRORPARAM 211
#define IDD_UNWRAP_PARAMS 212
#define IDD_PASTE_NAMEDSET 213
#define IDD_SEL_NAMEDSET 214
#define IDD_WINDGRAV_SOT 215
#define IDC_ANGLE 1000
#define IDC_X 1001
#define IDC_PHASE 1001
#define IDC_Y 1002
#define IDC_Z 1003
#define IDC_RADIUS 1004
#define IDC_DIR 1004
#define IDC_TWIST_BIAS 1004
#define IDC_ANGLESPINNER 1005
#define IDC_MODNOISE_SEED 1005
#define IDC_RADSPINNER 1006
#define IDC_DIRSPINNER 1006
#define IDC_TWIST_BIASSPIN 1006
#define IDC_CRV 1007
#define IDC_PHASESPINNER 1007
#define IDC_MODNOISE_SEEDSPIN 1007
#define IDC_OPT_BIAS 1007
#define IDC_DISP_UTILE 1007
#define IDC_NS_LIST 1007
#define IDC_AMT 1008
#define IDC_DECAYSPINNER 1008
#define IDC_MODNOISE_ROUGHNESS 1008
#define IDC_OPT_BIASSPIN 1008
#define IDC_DISP_UTILESPIN 1008
#define IDC_SET_NAME 1008
#define IDC_AMTSPINNER 1009
#define IDC_DECAY 1009
#define IDC_MODNOISE_ROUGHNESSSPIN 1009
#define IDC_DISP_VTILE 1009
#define IDC_OPT_MAXEDGE 1009
#define IDC_CRVSPINNER 1010
#define IDC_MODNOISE_ITERATIONS 1010
#define IDC_DISP_VTILESPIN 1010
#define IDC_OPT_MAXEDGESPIN 1010
#define IDC_AMPLITUDE 1011
#define IDC_TAPER_FROM 1011
#define IDC_MODNOISE_ITERATIONSSPIN 1011
#define IDC_DISP_STRENGTH 1011
#define IDC_AMPSPINNER 1012
#define IDC_TAPER_TO 1012
#define IDC_DISP_STRENGTHSPIN 1012
#define IDC_WAVELEN 1013
#define IDC_TAPER_FROMSPIN 1013
#define IDC_DISP_DECAY 1013
#define IDC_WAVELENSPINNER 1014
#define IDC_TAPER_TOSPIN 1014
#define IDC_DISP_DECAYSPIN 1014
#define IDC_CIRCLES 1015
#define IDC_DISP_BLUR 1015
#define IDC_CIRCLESSPINNER 1016
#define IDC_DISP_BLURSPIN 1016
#define IDC_SEGS 1017
#define IDC_DISP_CENTERL 1017
#define IDC_SEGSPINNER 1018
#define IDC_DISP_CENTERLSPIN 1018
#define IDC_DIVISIONS 1019
#define IDC_DIVSPINNER 1020
#define IDC_FLEX 1021
#define IDC_STRENGTH 1021
#define IDC_AMPSPINNER2 1021
#define IDC_FLEXSPINNER 1022
#define IDC_STRENGTHSPIN 1022
#define IDC_AMPLITUDE2 1022
#define IDC_AUTHORIZE 1023
#define IDC_GRAVITYSPIN 1023
#define IDC_LOCKID 1024
#define IDC_GRAVITY 1024
#define IDC_EDIT2 1025
#define IDC_DETONATIONSPIN 1025
#define IDC_DETACH 1026
#define IDC_DETONATION 1026
#define IDC_TESSELLATE 1027
#define IDC_BOMB_CHAOSSPIN 1027
#define IDC_AFFECTREGION 1028
#define IDC_EXPLODE 1028
#define IDC_BOMB_CHAOS 1028
#define IDC_BACKFACE_VERTS 1029
#define IDC_WELDTHRESH 1030
#define IDC_THRESHSPINNER 1031
#define IDC_EXTRUDEAMOUNT 1033
#define IDC_EXTRUDESPINNER 1034
#define IDC_PLANARSPINNER 1035
#define IDC_SMOOTH_THRESHSPIN 1035
#define IDC_TES_EDGE 1036
#define IDC_SMOOTH_THRESH 1036
#define IDC_TES_CENTER 1037
#define IDC_NORMAL_SCALESPIN 1037
#define IDC_TENSIONSPINNER 1038
#define IDC_NORMAL_SCALE 1038
#define IDC_TENSION 1039
#define IDC_MAT_IDSPIN 1039
#define IDC_EXTRUDE 1040
#define IDC_MAT_ID 1040
#define IDC_WELD 1041
#define IDC_PLANAR 1041
#define IDC_COLLAPSE 1042
#define IDC_EDITCURVE 1042
#define IDC_INSERT 1042
#define IDC_Break 1043
#define IDC_VERTBREAK 1043
#define IDC_LEVEL 1043
#define IDC_MAKEPLANAR 1043
#define IDC_REFINE 1044
#define IDC_LEVELSPINNER 1044
#define IDC_BUILDFACE 1044
#define IDC_MAKEFIRST 1044
#define IDC_SELTYPE 1045
#define IDC_VERTREFINE 1045
#define IDC_TES_FACE_TRI 1045
#define IDC_CLOSE 1046
#define IDC_ANGLETHRESHSPIN 1046
#define IDC_OUTLINE 1047
#define IDC_ANGLETRESH 1047
#define IDC_TES_FACE_POLY 1047
#define IDC_BOOLEAN 1048
#define IDC_DELETEFACE 1048
#define IDC_OUTCENTER 1049
#define IDC_FACE_HIDE 1049
#define IDC_DETACHCOPY 1050
#define IDC_CONNECT 1050
#define IDC_FACE_UNHIDEALL 1050
#define IDC_SEGBREAK 1051
#define IDC_DELETE 1051
#define IDC_DELETESPLINE 1051
#define IDC_ATTACH 1052
#define IDC_SEGDELETE 1052
#define IDC_ATTACHCUR 1052
#define IDC_MIRROR 1052
#define IDC_OUTLINEWIDTH 1053
#define IDC_CREATELINE 1053
#define IDC_OUTLINESPINNER 1054
#define IDC_DETACH_NAME 1055
#define IDC_ALIGNLEFT 1055
#define IDC_ALIGNMIN 1055
#define IDC_MIRRORCOPY 1055
#define IDC_RETAIN_ORIENT 1056
#define IDC_GETSHAPE 1056
#define IDC_CONST_ORIENT 1057
#define IDC_LOCK_HANDLES 1057
#define IDC_LOCKALIKE 1058
#define IDC_ALIGNCENTER 1058
#define IDC_LOCKALL 1059
#define IDC_BOOLTYPE 1059
#define IDC_ALIGNRIGHT 1059
#define IDC_ALIGNMAX 1059
#define IDC_ATTACHREORIENT 1060
#define IDC_MIRRORTYPE 1060
#define IDC_DETACHREORIENT 1061
#define IDC_VERTDELETE 1062
#define IDC_AMOUNT 1063
#define IDC_AMOUNTSPINNER 1064
#define IDC_SMOOTH_GRP1 1064
#define IDC_SEGMENTSPINNER 1065
#define IDC_SMOOTH_GRP2 1065
#define IDC_ADDTRI 1065
#define IDC_SEGMENTS 1066
#define IDC_SMOOTH_GRP3 1066
#define IDC_ADDQUAD 1066
#define IDC_CAPSTART 1067
#define IDC_SMOOTH_GRP4 1067
#define IDC_CAPEND 1068
#define IDC_SMOOTH_GRP5 1068
#define IDC_SMOOTH_GRP6 1069
#define IDC_SECDELETE 1070
#define IDC_SMOOTH_GRP7 1070
#define IDC_SHAPESTEPS 1070
#define IDC_GETPATH 1071
#define IDC_SECALIGN 1071
#define IDC_SMOOTH_GRP8 1071
#define IDC_SECCENTER 1072
#define IDC_SMOOTH_GRP9 1072
#define IDC_ALIGNTYPES 1073
#define IDC_SMOOTH_GRP10 1073
#define IDC_SMOOTH_GRP11 1074
#define IDC_VERT_DELETE 1075
#define IDC_SMOOTH_GRP12 1075
#define IDC_VERT_CREATE 1076
#define IDC_SMOOTH_GRP13 1076
#define IDC_EXP_OBJECTS 1077
#define IDC_VERT_COLLAPSE 1077
#define IDC_SMOOTH_GRP14 1077
#define IDC_EXP_ELEMENTS 1078
#define IDC_SMOOTH_GRP15 1078
#define IDC_VERT_DETACH 1078
#define IDC_OBJ_ATTACH 1079
#define IDC_SMOOTH_GRP16 1079
#define IDC_EDGE_DIVIDE 1080
#define IDC_SMOOTH_GRP17 1080
#define IDC_EDGE_TURN 1081
#define IDC_VERT_WELD 1081
#define IDC_SMOOTH_GRP18 1081
#define IDC_EDGE_VIS 1082
#define IDC_SMOOTH_GRP19 1082
#define IDC_VERT_WELDTOVERT 1082
#define IDC_EDGE_INVIS 1083
#define IDC_SMOOTH_GRP20 1083
#define IDC_EDGE_AUTO 1084
#define IDC_WELDTHRESHSPIN 1084
#define IDC_SMOOTH_GRP21 1084
#define IDC_EDGE_DELETE 1085
#define IDC_FACE_DETACH 1085
#define IDC_SMOOTH_GRP22 1085
#define IDC_EDGE_COLLAPSE 1086
#define IDC_FALLOFF 1086
#define IDC_SMOOTH_GRP23 1086
#define IDC_FALLOFFSPIN 1087
#define IDC_SMOOTH_GRP24 1087
#define IDC_EDGE_COPYNS 1087
#define IDC_PINCHSPIN 1088
#define IDC_SMOOTH_GRP25 1088
#define IDC_EDGE_PASTENS 1088
#define IDC_SPIN 1088
#define IDC_PINCH 1089
#define IDC_SMOOTH_GRP26 1089
#define IDC_SPINSPIN 1089
#define IDC_BUBBLESPIN 1090
#define IDC_SMOOTH_GRP27 1090
#define IDC_MINFRAG 1090
#define IDC_BUBBLE 1091
#define IDC_SMOOTH_GRP28 1091
#define IDC_MINFRAGSPIN 1091
#define IDC_NEARLABEL 1092
#define IDC_SMOOTH_GRP29 1092
#define IDC_MAXFRAG 1092
#define IDC_FARLEFTLABEL 1093
#define IDC_SMOOTH_GRP30 1093
#define IDC_MAXFRAGSPIN 1093
#define IDC_FARRIGHTLABEL 1094
#define IDC_SMOOTH_GRP31 1094
#define IDC_SEED 1094
#define IDC_AR_GRAPH 1095
#define IDC_SMOOTH_GRP32 1095
#define IDC_SEEDSPIN 1095
#define IDC_TENSTEXT 1096
#define IDC_TAPER_AFFECTREGION 1098
#define IDC_EFFECT_X 1104
#define IDC_EFFECT_Y 1105
#define IDC_EFFECT_BOTH 1106
#define IDC_TAPER_SYMMETRY 1107
#define IDC_BEND_AFFECTREGION 1108
#define IDC_BEND_TO 1109
#define IDC_BEND_TOSPIN 1110
#define IDC_BEND_FROM 1111
#define IDC_BEND_FROMSPIN 1112
#define IDC_TWIST_AFFECTREGION 1113
#define IDC_MODNOISE_FRACTAL 1113
#define IDC_TWIST_TO 1114
#define IDC_MODNOISE_ANIMATE 1114
#define IDC_TWIST_TOSPIN 1115
#define IDC_TWIST_FROM 1116
#define IDC_TWIST_FROMSPIN 1117
#define IDC_SKEW_AMOUNT 1118
#define IDC_SKEW_AMOUNTSPIN 1119
#define IDC_SKEW_AFFECTREGION 1120
#define IDC_SKEW_TO 1121
#define IDC_SKEW_TOSPIN 1122
#define IDC_SKEW_FROM 1123
#define IDC_SKEW_FROMSPIN 1124
#define IDC_MODNOISE_XSTRENGTH 1127
#define IDC_MODNOISE_XSTRENGTHSPIN 1128
#define IDC_MODNOISE_YSTRENGTH 1129
#define IDC_MODNOISE_YSTRENGTHSPIN 1130
#define IDC_MODNOISE_ZSTRENGTH 1131
#define IDC_MODNOISE_ZSTRENGTHSPIN 1132
#define IDC_MODNOISE_SCALE 1133
#define IDC_MODNOISE_SCALESPIN 1134
#define IDC_MODNOISE_ROUGHNESSLABEL 1135
#define IDC_MODNOISE_FREQ 1136
#define IDC_OPT_PRESERVEMAT 1136
#define IDC_MODNOISE_FREQSPIN 1137
#define IDC_OPT_RENDERL1 1137
#define IDC_OPT_RENDERL2 1138
#define IDC_MODNOISE_PHASE 1138
#define IDC_OPT_VIEWSL1 1139
#define IDC_MODNOISE_PHASESPIN 1139
#define IDC_OPT_VIEWSL2 1140
#define IDC_MODNOISE_ITERATIONSLABEL 1140
#define IDC_OPT_FACETHRESH 1141
#define IDC_OPT_FACETHRESHSPIN 1142
#define IDC_OPT_EDGETHRESH 1143
#define IDC_OPT_EDGETHRESHSPIN 1144
#define IDC_OPT_PRESERVESMOOTH 1145
#define IDC_OPT_AUTOEDGE 1146
#define IDC_OPT_VERTCOUNT 1147
#define IDC_OPT_FACECOUNT 1148
#define IDC_DISP_PLANAR 1149
#define IDC_DISP_CYL 1150
#define IDC_DISP_SPHERE 1151
#define IDC_DISP_USEMAP 1152
#define IDC_DISP_APPLYMAP 1153
#define IDC_DISP_CENTERLUM 1154
#define IDC_DISP_PICKIMAGE 1155
#define IDC_DISP_REMOVEIMAGE 1156
#define IDC_CLUST_PICKNODE 1157
#define IDC_DISP_PICKMAP 1157
#define IDC_CLUST_NODENAME 1158
#define IDC_DISP_REMOVEMAP 1158
#define IDC_DISPLENGTH 1161
#define IDC_DISPLENGTHSPIN 1162
#define IDC_WIND_STRENGTH 1163
#define IDC_WIND_STRENGTHSPIN 1164
#define IDC_FORCE_PLANAR 1165
#define IDC_FORCE_SPHERICAL 1166
#define IDC_WIND_DECAYSPIN 1167
#define IDC_WIND_DECAY 1168
#define IDC_WIND_TURBSPIN 1169
#define IDC_WIND_TURB 1170
#define IDC_GRAV_STRENGTH 1171
#define IDC_WIND_FREQSPIN 1171
#define IDC_GRAV_STRENGTHSPIN 1172
#define IDC_WIND_FREQ 1172
#define IDC_GRAV_DECAY 1173
#define IDC_WIND_SCALESPIN 1173
#define IDC_GRAV_DECAYSPIN 1174
#define IDC_WIND_SCALE 1174
#define IDC_DEFLECT_BOUNCE 1175
#define IDC_DEFLECT_BOUNCESPIN 1176
#define IDC_DEFLECT_WIDTH 1177
#define IDC_DEFLECT_WIDTHSPIN 1178
#define IDC_DEFLECT_HEIGHTSPIN 1179
#define IDC_MAP_PLANAR 1179
#define IDC_DEFLECT_HEIGHT 1180
#define IDC_MAP_CYL 1180
#define IDC_MAP_SPHERE 1181
#define IDC_MAP_BALL 1182
#define IDC_MAP_FIT 1183
#define IDC_MAP_CENTER 1184
#define IDC_MAP_VIEWALIGN 1185
#define IDC_MAP_NORMALALIGN 1186
#define IDC_MAP_BOX 1187
#define IDC_MAP_FITREGION 1188
#define IDC_MAP_BITMAPFIT 1189
#define IDC_MAP_UFLIP 1190
#define IDC_MAP_VFLIP 1191
#define IDC_MAP_UTILESPIN 1192
#define IDC_MAP_VTILESPIN 1193
#define IDC_MAP_VTILE 1194
#define IDC_MAP_UTILE 1195
#define IDC_MAP_WTILE 1196
#define IDC_SMOOTH_AUTO 1196
#define IDC_MAP_WTILESPIN 1197
#define IDC_NORMAL_FLIP 1197
#define IDC_SMOOTH_PREVENTINDIRECT 1197
#define IDC_MAP_WFLIP 1198
#define IDC_NORMAL_UNIFY 1198
#define IDC_NORMAL_SHOW 1199
#define IDC_MAP_UOFFSET 1199
#define IDC_MAP_RESET2 1199
#define IDC_MAP_RESET 1199
#define IDC_SELECT_BYID 1200
#define IDC_CLEARSELECTION 1200
#define IDC_MAP_VOFFSET 1200
#define IDC_MAP_ACQUIRE2 1200
#define IDC_MAP_ACQUIRE 1200
#define IDC_SELECTBYSMOOTH 1201
#define IDC_SEL_OBJECT 1201
#define IDC_MAP_WOFFSET 1201
#define IDC_MAP_FACE 1201
#define IDC_SEL_VERTEX 1202
#define IDC_MAP_UOFFSETSPIN 1202
#define IDC_MAP_LENGTH 1202
#define IDC_SEL_FACE 1203
#define IDC_MAP_VOFFSETSPIN 1203
#define IDC_MAP_WIDTH 1203
#define IDC_SEL_ADD 1204
#define IDC_MAP_WOFFSETSPIN 1204
#define IDC_MAP_HEIGHT 1204
#define IDC_SEL_SUBTRACT 1205
#define IDC_MAP_LENGTHSPIN 1205
#define IDC_SEL_REPLACE 1206
#define IDC_MAP_WIDTHSPIN 1206
#define IDC_SEL_WINDOW 1207
#define IDC_MAP_HEIGHTSPIN 1207
#define IDC_SEL_CROSSING 1208
#define IDC_SEL_BOX 1209
#define IDC_SEL_SPHERE 1210
#define IDC_SEL_CYLINDER 1211
#define IDC_SEL_FIT 1212
#define IDC_SEL_CENTER 1213
#define IDC_SEL_RESET 1214
#define IDC_MATID 1215
#define IDC_MATIDSPIN 1216
#define IDC_SEL_INVERT 1218
#define IDC_NORM_UNIFY 1219
#define IDC_NORM_FLIP 1220
#define IDC_MAP_CAP 1220
#define IDC_DEGREES 1221
#define IDC_DEGREESSPINNER 1222
#define IDC_MORPHCAP 1223
#define IDC_GRIDCAP 1224
#define IDC_WELDCORE 1226
#define IDC_DISPLATTICE 1229
#define IDC_DISPSURFACE 1230
#define IDC_DELETEPATCH 1231
#define IDC_DISPCONTROL 1232
#define IDC_DELETEVERT 1232
#define IDC_SUBDIVIDE 1233
#define IDC_PROPAGATE 1235
#define IDC_ADAPTIVE 1236
#define IDC_STEPS 1237
#define IDC_STEPSSPINNER 1238
#define IDC_DISP_BALL 1239
#define IDC_TESS_U_SPINNER 1239
#define IDC_TESS_U 1240
#define IDC_TESS_V_SPINNER 1241
#define IDC_DISP_WTILE 1242
#define IDC_TESS_V 1242
#define IDC_DISP_WTILESPIN 1243
#define IDC_TESS_DIST_SPINNER 1243
#define IDC_DISP_WFLIP 1244
#define IDC_TESS_DIST 1244
#define IDC_DISP_VFLIP 1245
#define IDC_TESS_ANG_SPINNER 1245
#define IDC_DISP_UFLIP 1246
#define IDC_TESS_ANG 1246
#define IDC_DISP_FIT 1247
#define IDC_TESS_EDGE_SPINNER 1247
#define IDC_DISP_CENTER 1248
#define IDC_TESS_EDGE 1248
#define IDC_DISP_BITMAPFIT 1249
#define IDC_DISP_NORMALALIGN 1250
#define IDC_DISP_RESET 1251
#define IDC_VERT_HIDE 1252
#define IDC_DISP_ACQUIRE 1252
#define IDC_VERT_UNHIDEALL 1253
#define IDC_PATCH 1254
#define IDC_MESH 1255
#define IDC_FILTVERTS 1255
#define IDC_FILTVECS 1256
#define IDC_SEL_BYVERT 1256
#define IDC_GENMAPPING 1257
#define IDC_FLIPNORMALS 1258
#define IDC_SPLINE_VERT_COUNT 1259
#define IDC_GEN_MATIDS 1259
#define IDC_SPLINE_VERT_COUNT_TITLE 1260
#define IDC_RESETTM_SELECTED 1261
#define IDC_AFR_FALLOFF 1262
#define IDC_AFR_FALLOFFSPIN 1263
#define IDC_AFR_BACKFACE 1264
#define IDC_EXT_SCALE 1264
#define IDC_EXT_SCALESPIN 1265
#define IDC_AFR_PINCH 1266
#define IDC_TENSIONSPIN 1266
#define IDC_AFR_PINCHSPIN 1267
#define IDC_ITERATIONS1 1267
#define IDC_AFR_BUBBLE 1268
#define IDC_ITERATIONS2 1268
#define IDC_MESHSEL_GETVERT 1268
#define IDC_AFR_BUBBLESPIN 1269
#define IDC_ITERATIONS3 1269
#define IDC_MESHSEL_GETFACE 1269
#define IDC_ITERATIONS4 1270
#define IDC_MESHSEL_GETEDGE 1270
#define IDC_MESHSEL_SELOPEN 1270
#define IDC_EXT_CENTER 1271
#define IDC_MESHSEL_SELBYMAT 1271
#define IDC_EXT_AMOUNT 1272
#define IDC_EXT_AMOUNTSPIN 1273
#define IDC_DISP_VIEWALIGN 1274
#define IDC_DISP_FITREGION 1275
#define IDS_MIRROR_X 1277
#define IDS_MIRROR_Y 1278
#define IDS_MIRROR_Z 1279
#define IDS_MIRROR_XY 1280
#define IDS_MIRROR_YZ 1281
#define IDS_MIRROR_ZX 1282
#define IDC_MIRROR_COPY 1283
#define IDC_MIRROR_OFFSET 1284
#define IDC_MIRROR_OFFSETSPIN 1285
#define IDC_IGNORE_BACKFACES 1286
#define IDC_IGNORE_VISEDGE 1287
#define IDC_UNWRAP_EDIT 1287
#define IDC_UNWARP_TOOLBAR 1288
#define IDC_UNWRAP_RESET 1288
#define IDC_SCROLLBAR1 1289
#define IDC_UNWRAP_VIEW 1290
#define IDC_UNWRAP_LINECOLOR 1291
#define IDC_UNWRAP_XOR 1292
#define IDC_UNWRAP_SELCOLOR 1293
#define IDC_UNWRAP_CONSTANTUPDATE 1294
#define IDC_UNWRAP_WIDTH 1295
#define IDC_UNWRAP_WIDTHSPIN 1296
#define IDC_UNWRAP_HEIGHT 1297
#define IDC_UNWRAP_HEIGHTSPIN 1298
#define IDC_UNWRAP_DEFAULTS 1299
#define IDC_FACE_COPYNS 1301
#define IDC_TESS_VIEW 1301
#define IDC_FACE_PASTENS 1302
#define IDC_TESS_RENDERER 1302
#define IDC_VERT_COPYNS 1303
#define IDC_TESS_SET 1303
#define IDC_VERT_PASTENS 1304
#define IDC_OPT_UPDATE 1305
#define IDC_TESS_PARAM 1305
#define IDC_OPT_MANUPDATE 1306
#define IDC_TESS_SPATIAL 1306
#define IDC_TESS_CURV 1307
#define IDC_DISP_CAP 1307
#define IDC_TESS_VIEW_DEP 1308
#define IDC_NUMSEL_LABEL 1309
#define IDC_MAP_CHAN1 1310
#define IDC_LENGTH_LABEL 1311
#define IDC_MAP_CHAN2 1312
#define IDC_WIDTH_LABEL 1313
#define IDC_HEIGHT_LABEL 1314
#define IDC_MAP_X 1315
#define IDC_MAP_Y 1316
#define IDC_MAP_Z 1317
#define IDC_DISP_LENGTH 1318
#define IDC_DISP_LENGTHSPIN 1319
#define IDC_DISP_WIDTH 1320
#define IDC_DISP_WIDTHSPIN 1321
#define IDC_DISP_HEIGHT 1322
#define IDC_DISP_HEIGHTSPIN 1323
#define IDC_DISP_X 1324
#define IDC_DISP_Y 1325
#define IDC_DISP_Z 1326
#define IDC_NURBS 1327
#define IDC_UNWRAP_U 1328
#define IDC_UNWRAP_USPIN 1329
#define IDC_UNWRAP_ULABEL 1330
#define IDC_UNWRAP_V 1331
#define IDC_FALLOFF_ON 1331
#define IDC_UNWRAP_VSPIN 1332
#define IDC_UNWRAP_VLABEL 1333
#define IDC_UNWRAP_W 1334
#define IDC_UNWRAP_WSPIN 1335
#define IDC_UNWRAP_WLABEL 1336
#define IDC_ACQUIRE_REL 1552
#define IDC_ACQUIRE_ABS 1553
#define IDC_SELSINGLE 5000
#define IDC_SELPOLY 5001
#define IDC_SELELEMENT 5002
#define IDC_BOOLUNION 5010
#define IDC_BOOLSUBTRACTION 5011
#define IDC_BOOLINTERSECTION 5012
#define IDS_DS_MOVE2 10004
#define IDS_DS_SELECT 10007
#define IDS_DS_CREATE 10008
#define IDS_RB_EXTRUDE 30001
#define IDS_RB_TAPER 30003
#define IDS_RB_OBJECT 30004
#define IDS_RB_EDITMESH 30009
#define IDS_RB_EDITMESHTOOLS 30010
#define IDS_RB_VERTEX 30011
#define IDS_RB_FACE 30012
#define IDS_RB_EDGE 30013
#define IDS_RB_CENTER 30014
#define IDS_RB_APPARATUS 30015
#define IDS_RB_EDITVERTEX 30016
#define IDS_RB_EDITOBJECT 30017
#define IDS_RB_EDITFACE 30018
#define IDS_RB_EDITEDGE 30019
#define IDS_RB_EDITPOLY 30020
#define IDS_RB_EDITELEMENT 30021
#define IDS_RB_EDITMESH_CLASS 30022
#define IDS_RB_PARAMETERS 30028
#define IDS_RB_ANGLE 30029
#define IDS_RB_DIRECTION 30030
#define IDS_RB_AMOUNT 30031
#define IDS_RB_AMOUNT2 30032
#define IDS_RB_CURVITURE 30033
#define IDS_RB_AMPLITUDE 30034
#define IDS_RB_WAVELEN 30035
#define IDS_RB_PHASE 30036
#define IDS_RB_DECAY 30037
#define IDS_RB_FLEXIBILITY 30038
#define IDS_RB_WIDTH 30039
#define IDS_RB_HEIGHT 30040
#define IDS_DB_EXTRUDE 30041
#define IDS_RB_NONE 30137
#define IDS_RB_RIPPLE 30155
#define IDS_RB_RIPPLE_BINDING 30156
#define IDS_RB_DELETEVERT 30211
#define IDS_RB_DELETEFACE 30212
#define IDS_RB_ADDVERTS 30213
#define IDS_RB_ATTACHOBJECT 30214
#define IDS_RB_FACECOLLAPSE 30215
#define IDS_RB_MAKEPLANAR 30216
#define IDS_RB_BUILDFACE 30217
#define IDS_RB_HIDEFACE 30218
#define IDS_RB_UNHIDEALLFACES 30219
#define IDS_RB_EDGEVISIBLE 30220
#define IDS_RB_EDGEINVISIBLE 30221
#define IDS_RB_AUTOEDGE 30222
#define IDS_RB_EDGEDIVIDE 30223
#define IDS_RB_EDGETURN 30224
#define IDS_RB_DELETEEDGE 30225
#define IDS_RB_COLLAPSEEDGE 30226
#define IDS_RB_CLONE 30227
#define IDS_RB_TESSELLATE 30228
#define IDS_RB_DELETEISOLATED 30229
#define IDS_RB_DEFDEFORMATIONS 30270
#define IDS_RB_DEFEDIT 30271
#define IDS_RB_NODEXFORM 30276
#define IDS_RB_NODEXFORM_CLASS 30277
#define IDS_RB_XFORM_CLASS 30278
#define IDS_RB_EDITSURFACE 30279
#define IDS_RB_SETSMOOTHGROUP 30280
#define IDS_RB_ASSIGNMATID 30281
#define IDS_RB_FLIPNORMALS 30282
#define IDS_RB_UNIFYNORMALS 30283
#define IDS_RB_AUTOSMOOTH 30284
#define IDS_RB_SELECTBYMATID 30285
#define IDS_RB_SELECTBYSMOOTH 30286
#define IDS_RB_SOT 30287
#define IDS_RB_DEFLECTOR_CLASS 30288
#define IDS_RB_HIDEVERT 30294
#define IDS_RB_DEFSURFACE 30298
#define IDS_RB_SCALE 30377
#define IDS_RB_NOISE 30411
#define IDS_RB_ROTATION2 30521
#define IDS_RB_TWIST 30522
#define IDS_RB_BENDMOD 30543
#define IDS_RB_BEND2 30544
#define IDS_RB_FROM 30545
#define IDS_RB_TO 30546
#define IDS_RB_BOMBOBJECT 30547
#define IDS_RB_BOMB 30548
#define IDS_RB_BOMBMOD 30549
#define IDS_RB_BOMBBINDING 30550
#define IDS_RB_CLUSTNODEMOD 30551
#define IDS_RB_XFORM 30552
#define IDS_RB_DEFLECTOR 30553
#define IDS_RB_DEFLECTMOD 30554
#define IDS_RB_DEFLECTORBINDING 30555
#define IDS_RB_BOUNCE 30556
#define IDS_RB_DISPMOD 30557
#define IDS_RB_DISPLACE 30558
#define IDS_RB_DISPLACEMOD 30559
#define IDS_RB_DISPLACEBINDING 30560
#define IDS_RB_SELECTDISPIMAGE 30561
#define IDS_RB_SELECTIMAGE 30562
#define IDS_RB_UTILE 30563
#define IDS_RB_VTILE 30564
#define IDS_RB_WTILE 30565
#define IDS_RB_BLUR 30566
#define IDS_RB_DOCREATENEWOBJECT 30567
#define IDS_RB_EDITMESH2 30568
#define IDS_RB_GRAVITY 30569
#define IDS_RB_WIND 30570
#define IDS_RB_GRAVITYMOD 30571
#define IDS_RB_GRAVITYBINDING 30572
#define IDS_RB_WINDMOD 30573
#define IDS_RB_WINDBINDING 30574
#define IDS_RB_TURBULENCE 30575
#define IDS_RB_FREQUENCY 30576
#define IDS_RB_MAPMOD 30577
#define IDS_RB_UVWMAPPING 30578
#define IDS_RB_UVWMAP 30579
#define IDS_RB_NOISEMOD 30580
#define IDS_RB_SEED 30581
#define IDS_RB_FRACTAL 30582
#define IDS_RB_ROUGH 30583
#define IDS_RB_ITERATIONS 30584
#define IDS_RB_OPTMOD 30585
#define IDS_RB_OPTIMIZE 30586
#define IDS_RB_FACETHRESHL1 30587
#define IDS_RB_FACETHRESHL2 30588
#define IDS_RB_EDGETHRESHL1 30589
#define IDS_RB_EDGETHRESHL2 30590
#define IDS_RB_BIASL1 30591
#define IDS_RB_BIASL2 30592
#define IDS_RB_EDITMESHMOD 30593
#define IDS_RB_TWISTMOD 30594
#define IDS_RB_TWIST2 30595
#define IDS_RB_TWISTPLUGIN 30596
#define IDS_RB_BIAS 30597
#define IDS_RB_INCORRECTSTRING 30598
#define IDS_RB_AUTHORIZATION 30599
#define IDS_RB_TAPERMOD 30600
#define IDS_RB_SYMMETRY 30601
#define IDS_RB_MATMOD 30602
#define IDS_RB_MATERIAL3 30603
#define IDS_RB_MATERIALID 30604
#define IDS_RB_MATERIAL4 30605
#define IDS_RB_MATERIALID2 30606
#define IDS_RB_SMOOTHMOD 30607
#define IDS_RB_NORMALMOD 30608
#define IDS_RB_SKEWMOD 30609
#define IDS_RB_SKEW 30610
#define IDS_RB_SMOOTH2 30611
#define IDS_RB_WAVE 30612
#define IDS_RB_WAVEMOD 30613
#define IDS_RB_WAVEBINDING 30614
#define IDS_RB_AMPLITUDE1 30615
#define IDS_RB_AMPLITUDE2 30616
#define IDS_RB_VOLSELECT 30617
#define IDS_RB_THRESHOLD 30618
#define IDS_RB_GIZMO 30619
#define IDS_RB_NORMAL 30620
#define IDS_RB_BEND_CLASS 30621
#define IDS_RB_DISPLACE_CLASS 30622
#define IDS_RB_VOLSELECT_CLASS 30623
#define IDS_RB_SKEW_CLASS 30624
#define IDS_RB_MATERIAL3_CLASS 30625
#define IDS_RB_SMOOTH2_CLASS 30626
#define IDS_RB_NORMAL_CLASS 30627
#define IDS_TH_LATHE_CLASS 30628
#define IDS_RB_EXPLODE 30629
#define IDS_RB_COLLAPSE 30630
#define IDS_RB_WELDVERTS 30631
#define IDS_RB_TAPER_CLASS 30632
#define IDS_RB_TWIST2_CLASS 30633
#define IDS_RB_TWIST_CLASS 30634
#define IDS_RB_BOMBOBJECT_CLASS 30635
#define IDS_RB_BOMB_CLASS 30636
#define IDS_RB_RIPPLE_CLASS 30637
#define IDS_RB_WAVE_CLASS 30638
#define IDS_RB_STRENGTH2 30646
#define IDS_DS_MOVE 30647
#define IDS_RB_FACESEL 30651
#define IDS_RB_POLYGONSEL 30652
#define IDS_RB_ELEMENTSEL 30653
#define IDS_RB_NOVERTSTOWELD 30680
#define IDS_RB_CHAOS 30681
#define IDS_RB_DETONATION 30682
#define IDS_RB_BOMBPARAMS 30683
#define IDS_RB_EDITMESHTITLE 30684
#define IDS_RB_DUPFACEWARNING 30685
#define IDS_RB_NUMVERTSELP 30699
#define IDS_RB_NUMVERTSEL 30700
#define IDS_RB_NUMFACESELP 30701
#define IDS_RB_NUMFACESEL 30702
#define IDS_RB_NUMEDGESELP 30703
#define IDS_RB_NUMEDGESEL 30704
#define IDS_TH_EDITSPLINE 40025
#define IDS_TH_EDITSEGMENT 40026
#define IDS_TH_EDITVERTEX 40027
#define IDS_TH_SPLINE 40028
#define IDS_TH_SEGMENT 40029
#define IDS_TH_VERTEX 40030
#define IDS_TH_EDITOBJECT 40031
#define IDS_TH_EDITPATCH_CLASS 40032
#define IDS_TH_EDITSPLINE_CLASS 40033
#define IDS_RB_EXTRUDE_CLASS 40034
#define IDS_RB_GRAVITY_CLASS 40035
#define IDS_RB_WIND_CLASS 40036
#define IDS_RB_UVWMAP_CLASS 40037
#define IDS_RB_NOISE_CLASS 40038
#define IDS_TH_CLOSESPLINE 40039
#define IDS_RB_OPTIMIZE_CLASS 40040
#define IDS_TH_DELETESPLINE 40041
#define IDS_TH_NOVALIDSPLINESSEL 40042
#define IDS_TH_NOSPLINESSEL 40043
#define IDS_TH_VERTBREAK 40044
#define IDS_TH_NOVALIDVERTSSEL 40045
#define IDS_TH_SEGDELETE 40046
#define IDS_TH_NOSEGSSEL 40047
#define IDS_TH_DETACHSPLINE 40048
#define IDS_TH_OUTLINE 40049
#define IDS_TH_SEGDETACH 40050
#define IDS_TH_SHAPE 40051
#define IDS_TH_REFINE 40052
#define IDS_TH_SEGBREAK 40053
#define IDS_TH_VERTCONNECT 40054
#define IDS_TH_VERTINSERT 40055
#define IDS_TH_VERTWELD 40056
#define IDS_TH_NOWELDPERFORMED 40057
#define IDS_TH_SELECTONESPLINE 40058
#define IDS_TH_MORETHANONESPLINESEL 40059
#define IDS_TH_BOOLEAN 40060
#define IDS_TH_UNION 40061
#define IDS_TH_SUBTRACTION 40062
#define IDS_TH_INTERSECTION 40063
#define IDS_TH_BOOLWELDFAILED 40064
#define IDS_TH_COINCIDENTVERTEX 40065
#define IDS_TH_SPLINESMUSTOVERLAP 40066
#define IDS_TH_SELECTCLOSEDSPLINE 40067
#define IDS_TH_SPLINESELFINTERSECTS 40068
#define IDS_TH_ATTACH 40069
#define IDS_TH_CANHAVEONLYONESHAPE 40070
#define IDS_TH_NOVERTSSEL 40071
#define IDS_TH_VERTCHANGE 40072
#define IDS_TH_SMOOTH 40073
#define IDS_TH_CORNER 40074
#define IDS_RB_RESETXFORM_CLASS 40075
#define IDS_TH_BEZIER 40076
#define IDS_TH_SEGCHANGE 40077
#define IDS_TH_CURVE 40078
#define IDS_TH_LINE 40079
#define IDS_TH_VERTDELETE 40080
#define IDS_TH_BEZIERCORNER 40081
#define IDS_TH_AMOUNT 40082
#define IDS_TH_EDITPATCH 40083
#define IDS_TH_PATCH 40084
#define IDS_TH_SEGMENTS 40085
#define IDS_TH_PATCHDELETE 40086
#define IDS_TH_NOPATCHESSEL 40087
#define IDS_TH_MAKEFIRST 40160
#define IDS_TH_EDITEDGE 40170
#define IDS_TH_EDGE 40171
#define IDS_TH_AUTOINTERIOR 40172
#define IDS_TH_MANUALINTERIOR 40173
#define IDS_TH_NOVALIDEDGESSEL 40174
#define IDS_TH_PATCHADD 40175
#define IDS_TH_EDGESUBDIVIDE 40176
#define IDS_TH_PATCHSUBDIVIDE 40177
#define IDS_TH_CREATELINE 40178
#define IDS_TH_MIRROR_H 40179
#define IDS_TH_MIRROR_V 40180
#define IDS_TH_MIRROR_BOTH 40181
#define IDS_TH_MIRROR 40182
#define IDS_TH_PATCHCHANGE 40186
#define IDS_TH_COPLANAR 40187
#define IDS_TH_POLYCONNECT 40190
#define IDS_TH_CONNECT_COINCIDENT 40191
#define IDS_TH_CANHAVEONLYONEPATCH 40192
#define IDS_TH_DETACHPATCH 40193
#define IDS_TH_COPY_SPLINE 40196
#define IDS_TH_COPY_SEGMENT 40197
#define IDS_TH_SPLINECHANGE 40201
#define IDS_TH_MIRRORSPLINE 40279
#define IDS_TH_DEGREES 40308
#define IDS_TH_AXIS 40309
#define IDS_TH_LATHE 40310
#define IDS_TH_VERTWELDRESULT 40316
#define IDS_RB_RESETXFORM 40317
#define IDS_RB_AFRMOD 40318
#define IDS_RB_STARTPOINT 40319
#define IDS_RB_ENDPOINT 40320
#define IDS_RB_AFRPOINTS 40321
#define IDS_AFR_FALLOFF 40322
#define IDS_AFR_PINCH 40323
#define IDS_AFR_BUBBLE 40324
#define IDS_RB_TESSMOD 40325
#define IDS_TESS_TENSION 40326
#define IDS_RB_DELETEMOD 40327
#define IDS_RB_MESHSELMOD 40328
#define IDS_RB_FACEEXTRUDEMOD 40329
#define IDS_RB_EXTRUDECENT 40330
#define IDS_EXT_AMOUNT 40331
#define IDS_EXT_SCALE 40332
#define IDS_RB_UVWXFORMMOD 40333
#define IDS_RB_UOFFSET 40334
#define IDS_RB_VOFFSET 40335
#define IDS_RB_WOFFSET 40336
#define IDS_RB_MAXEDGE1 40337
#define IDS_RB_MAXEDGE2 40338
#define IDS_RB_CENTERPOINT 40339
#define IDS_RB_MIRRORMOD 40340
#define IDS_RB_MIRRORCENTER 40341
#define IDS_RB_OFFSET 40342
#define IDS_RB_SELVERTEX 40343
#define IDS_RB_SELFACE 40344
#define IDS_RB_SELEDGE 40345
#define IDS_RB_SELOBJECT 40346
#define IDS_RB_UNWRAPMOD 40347
#define IDS_AP_SDELETEMOD 40348
#define IDS_RB_RESETUVWS 40349
#define IDS_RB_SETCHANNEL 40350
#define IDS_RB_SHOULDRESET 40351
#define IDS_RB_RESETUNWRAPUVWS 40352
#define IDS_RB_LENGTH 40353
#define IDS_SA_TRIANGLE 40354
#define IDS_SA_POLYGON 40355
#define IDS_SA_TRI_POLY_RESTORE 40356
#define IDS_RB_SPIN 40357
#define IDS_RB_FALLOFF 40358
#define IDS_TH_PATCHMTLCHANGE 40359
#define IDS_RB_MOVE 40360
#define IDS_RB_ROTATE 40361
#define IDS_RB_PAN 40362
#define IDS_RB_ZOOM 40363
#define IDS_RB_PICKMAP 40364
#define IDS_RB_UPDATE 40365
#define IDS_RB_ZOOMEXT 40366
#define IDS_RB_ZOOMREG 40367
#define IDS_RB_UVW 40368
#define IDS_RB_PROP 40369
#define IDS_RB_SHOWMAP 40370
#define IDS_RB_DEFMODS 40371
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 159
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1332
#define _APS_NEXT_SYMED_VALUE 107
#endif
#endif
@@ -0,0 +1,111 @@
/**********************************************************************
*<
FILE: mods.cpp
DESCRIPTION: DLL implementation of modifiers
CREATED BY: Rolf Berteig (based on prim.cpp)
HISTORY: created 30 January 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.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();
}
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_DEFMODS); }
/// MUST CHANGE THIS NUMBER WHEN ADD NEW CLASS
__declspec( dllexport ) int LibNumberClasses() {return 1;}
__declspec( dllexport ) ClassDesc*
LibClassDesc(int i) {
switch(i) {
case 0: return GetResetXFormDesc();
default: return 0;
}
}
// Return version so can detect obsolete DLLs
__declspec( dllexport ) ULONG
LibVersion() { return VERSION_3DSMAX; }
BOOL CALLBACK DefaultSOTProc(
HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
IObjParam *ip = (IObjParam*)GetWindowLong(hWnd,GWL_USERDATA);
switch (msg) {
case WM_INITDIALOG:
SetWindowLong(hWnd,GWL_USERDATA,lParam);
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
if (ip) ip->RollupMouseMessage(hWnd,msg,wParam,lParam);
return FALSE;
default:
return FALSE;
}
return TRUE;
}
TCHAR *GetString(int id)
{
static TCHAR buf[256];
if (hInstance)
return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL;
return NULL;
}
@@ -0,0 +1,238 @@
# Microsoft Developer Studio Project File - Name="mods" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=mods - Win32 Release
!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 "Mods.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 "Mods.mak" CFG="mods - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "mods - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "mods - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "mods - Win32 Hybrid" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "mods - 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 Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /G6 /MD /W3 /O2 /I "..\..\..\Libraries\3dsmax2\Include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Yu"mods.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 COMCTL32.LIB KERNEL32.LIB USER32.LIB GDI32.LIB WINSPOOL.LIB COMDLG32.LIB ADVAPI32.LIB SHELL32.LIB OLE32.LIB OLEAUT32.LIB UUID.LIB bmm.lib core.lib util.lib gfx.lib Mnmath.lib Mesh.lib Geom.lib /nologo /base:"0X28250000" /subsystem:windows /dll /machine:I386 /out:"Release\BetterXform.dlm" /libpath:"..\..\..\Libraries\3dsmax2\Rellib"
!ELSEIF "$(CFG)" == "mods - 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 Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /G6 /MDd /W3 /Gm /ZI /Od /I "..\..\..\Libraries\3dsmax2\Include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Yu"mods.h" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 COMCTL32.LIB KERNEL32.LIB USER32.LIB GDI32.LIB WINSPOOL.LIB COMDLG32.LIB ADVAPI32.LIB SHELL32.LIB OLE32.LIB OLEAUT32.LIB UUID.LIB bmm.lib core.lib util.lib gfx.lib Mnmath.lib Mesh.lib Geom.lib /nologo /base:"0X28250000" /subsystem:windows /dll /debug /machine:I386 /out:"Debug\BetterXform.dlm" /libpath:"..\..\..\Libraries\3dsmax2\Dbglib"
!ELSEIF "$(CFG)" == "mods - Win32 Hybrid"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\mods___W"
# PROP BASE Intermediate_Dir ".\mods___W"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Hybrid"
# PROP Intermediate_Dir ".\Hybrid"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G5 /MD /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Yu"mods.h" /c
# ADD CPP /nologo /G6 /MD /W3 /Gm /ZI /Od /I "..\..\..\Libraries\3dsmax2\Include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Yu"mods.h" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 COMCTL32.LIB KERNEL32.LIB USER32.LIB GDI32.LIB WINSPOOL.LIB COMDLG32.LIB ADVAPI32.LIB SHELL32.LIB OLE32.LIB OLEAUT32.LIB UUID.LIB /nologo /subsystem:windows /dll /debug /machine:I386 /out:"..\..\PLUGIN\MODS.DLM"
# ADD LINK32 COMCTL32.LIB KERNEL32.LIB USER32.LIB GDI32.LIB WINSPOOL.LIB COMDLG32.LIB ADVAPI32.LIB SHELL32.LIB OLE32.LIB OLEAUT32.LIB UUID.LIB bmm.lib core.lib util.lib gfx.lib Mnmath.lib Mesh.lib Geom.lib /nologo /base:"0X28250000" /subsystem:windows /dll /debug /machine:I386 /out:"Hybrid\BetterXform.dlm" /libpath:"..\..\..\Libraries\3dsmax2\Rellib"
!ENDIF
# Begin Target
# Name "mods - Win32 Release"
# Name "mods - Win32 Debug"
# Name "mods - Win32 Hybrid"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=.\mods.cpp
# ADD CPP /Yc"mods.h"
# End Source File
# Begin Source File
SOURCE=.\mods.def
# End Source File
# Begin Source File
SOURCE=.\mods.rc
# End Source File
# Begin Source File
SOURCE=.\resettm.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\MODS.H
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\addvertc.cur
# End Source File
# Begin Source File
SOURCE=.\attach.cur
# End Source File
# Begin Source File
SOURCE=.\bmp00001.bmp
# End Source File
# Begin Source File
SOURCE=.\bmp00002.bmp
# End Source File
# Begin Source File
SOURCE=.\booleant.bmp
# End Source File
# Begin Source File
SOURCE=.\boolinte.cur
# End Source File
# Begin Source File
SOURCE=.\boolsubt.cur
# End Source File
# Begin Source File
SOURCE=.\boolunio.cur
# End Source File
# Begin Source File
SOURCE=.\bulbmask.bmp
# End Source File
# Begin Source File
SOURCE=.\bulbs.bmp
# End Source File
# Begin Source File
SOURCE=.\extrudec.cur
# End Source File
# Begin Source File
SOURCE=.\faceselt.bmp
# End Source File
# Begin Source File
SOURCE=.\mask_boo.bmp
# End Source File
# Begin Source File
SOURCE=.\mask_fac.bmp
# End Source File
# Begin Source File
SOURCE=.\mask_unw.bmp
# End Source File
# Begin Source File
SOURCE=.\outline.cur
# End Source File
# Begin Source File
SOURCE=.\segbreak.cur
# End Source File
# Begin Source File
SOURCE=.\segrefin.cur
# End Source File
# Begin Source File
SOURCE=.\thselcur.cur
# End Source File
# Begin Source File
SOURCE=.\unwrapto.bmp
# End Source File
# Begin Source File
SOURCE=.\vertconn.cur
# End Source File
# Begin Source File
SOURCE=.\vinsert.cur
# End Source File
# End Group
# End Target
# End Project
@@ -0,0 +1,57 @@
/**********************************************************************
*<
FILE: mods.h
DESCRIPTION:
CREATED BY: Rolf Berteig (based on prim.h)
HISTORY:
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#ifndef __MODS__H
#define __MODS__H
#include "Max.h"
//#include "reslib.h"
#include "modsres.h"
TCHAR *GetString(int id);
#define EDITMESH_CLASS_ID 0x00050
#define EDITSPLINE_CLASS_ID 0x00060
#define EDITPATCH_CLASS_ID 0x00070
#define EDITLOFT_CLASS_ID 0x00080
#define CLUSTOSM_CLASS_ID 0x25215824
#define RESET_XFORM_CLASS_ID 0x8d562b81
#define CLUSTNODEOSM_CLASS_ID 0xc4d33
extern ClassDesc* GetResetXFormDesc();
// This is just temporary to make some extra mods so I can
// implement the 'more' system in the modify panel.
extern ClassDesc* GetBendModDesc2();
extern ClassDesc* GetBendModDesc3();
extern ClassDesc* GetBendModDesc4();
extern ClassDesc* GetBendModDesc5();
extern ClassDesc* GetSDeleteModDesc();
// in mods.cpp
extern HINSTANCE hInstance;
// For 'Supports Object of Type' rollups
extern BOOL CALLBACK DefaultSOTProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
#define BIGFLOAT float(999999)
#define NEWSWMCAT _T("Modifiers")
#endif
@@ -0,0 +1,42 @@
/**********************************************************************
*<
FILE: namesel.h
DESCRIPTION: A named sel set class for sub-object named selections ets
CREATED BY: Rolf Berteig
HISTORY: 3/18/96
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#ifndef __NAMEDSEL__
#define __NAMEDSEL__
class NamedSelSetList {
public:
Tab<BitArray*> sets;
Tab<DWORD> ids;
~NamedSelSetList();
BitArray *GetSet(DWORD id);
int Count() {return sets.Count();}
void AppendSet(BitArray &nset,DWORD id=0);
void RemoveSet(DWORD id);
IOResult Load(ILoad *iload);
IOResult Save(ISave *isave);
void SetSize(int size);
NamedSelSetList& operator=(NamedSelSetList& from);
void DeleteSetElements(BitArray &set,int m=1);
void DeleteSet(int i);
BitArray &operator[](int i) {return *sets[i];}
};
// RB: note these methods are implemented in editmesh.cpp.
// This class is used by the edit mesh and edit patch modifiers.
#endif
@@ -0,0 +1,469 @@
/**********************************************************************
*<
FILE: noisemod.cpp
DESCRIPTION: A Noise Modifier
CREATED BY: Rolf Berteig
HISTORY: created 18 October 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#include "simpmod.h"
#include "simpobj.h"
#include "texutil.h"
// in mods.cpp
extern HINSTANCE hInstance;
#define BIGFLOAT float(999999)
#define NOISEOSM_CLASS_ID 0xf997b124
class NoiseMod : public SimpleMod {
public:
static IParamMap *pmapParam;
NoiseMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) { s= GetString(IDS_RB_NOISEMOD); }
virtual Class_ID ClassID() {return Class_ID(NOISEOSM_CLASS_ID,0);}
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams( IObjParam *ip,ULONG flags,Animatable *next);
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() { return GetString(IDS_RB_NOISE); }
IOResult Load(ILoad *iload);
// From simple mod
Deformer& GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat);
Interval GetValidity(TimeValue t);
ParamDimension *GetParameterDim(int pbIndex);
TSTR GetParameterName(int pbIndex);
void InvalidateUI() {if (pmapParam) pmapParam->Invalidate();}
};
class NoiseDeformer: public Deformer {
public:
Matrix3 tm,invtm;
int fractal;
float scale, rough, iterations;
Point3 strength;
float time;
NoiseDeformer();
NoiseDeformer(
ModContext &mc,
TimeValue t,
int seed, float scale, int fractal, float iterations,
float rough, int anim, float freq,
Point3 strength,
TimeValue phase,
Matrix3& modmat, Matrix3& modinv);
Point3 Map(int i, Point3 p);
};
#define NOISEWSM_CLASSID Class_ID(NOISEOSM_CLASS_ID,1)
class NoiseWSM : public SimpleOSMToWSMObject {
public:
NoiseWSM() {}
NoiseWSM(NoiseMod *m) : SimpleOSMToWSMObject(m) {}
void DeleteThis() { delete this; }
SClass_ID SuperClassID() {return WSM_OBJECT_CLASS_ID;}
Class_ID ClassID() {return NOISEWSM_CLASSID;}
TCHAR *GetObjectName() {return GetString(IDS_RB_NOISE);}
RefTargetHandle Clone(RemapDir& remap)
{return (new NoiseWSM((NoiseMod*)mod->Clone(remap)))->SimpleOSMToWSMClone(this,remap);}
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *NoiseMod::pmapParam = NULL;
class NoiseClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new NoiseMod; }
const TCHAR * ClassName() { return GetString(IDS_RB_NOISE_CLASS); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(NOISEOSM_CLASS_ID,0); }
const TCHAR* Category() { return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static NoiseClassDesc noiseDesc;
extern ClassDesc* GetNoiseModDesc() { return &noiseDesc; }
class NoiseWSMClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE)
{if (loading) return new NoiseWSM; else return new NoiseWSM(new NoiseMod);}
const TCHAR * ClassName() { return GetString(IDS_RB_NOISE_CLASS); }
SClass_ID SuperClassID() { return WSM_OBJECT_CLASS_ID; }
Class_ID ClassID() { return NOISEWSM_CLASSID; }
const TCHAR* Category() {return GetSpaceWarpCatString(SPACEWARP_CAT_MODBASED);}
};
static NoiseWSMClassDesc noiseWSMDesc;
extern ClassDesc* GetNoiseWSMDesc() { return &noiseWSMDesc; }
//--- Parameter map/block descriptors -------------------------------
#define PB_SEED 0
#define PB_SCALE 1
#define PB_FRACTAL 2
#define PB_ROUGH 3
#define PB_ITERATIONS 4
#define PB_ANIMATE 5
#define PB_FREQ 6
#define PB_PHASE 7
#define PB_STRENGTH 8
//
//
// Parameters
static ParamUIDesc descParam[] = {
// Seed
ParamUIDesc(
PB_SEED,
EDITTYPE_INT,
IDC_MODNOISE_SEED,IDC_MODNOISE_SEEDSPIN,
0.0f,99999999.0f,
0.1f),
// Scale
ParamUIDesc(
PB_SCALE,
EDITTYPE_FLOAT,
IDC_MODNOISE_SCALE,IDC_MODNOISE_SCALESPIN,
0.0f,BIGFLOAT,
SPIN_AUTOSCALE),
// Fractal
ParamUIDesc(PB_FRACTAL,TYPE_SINGLECHEKBOX,IDC_MODNOISE_FRACTAL),
// Roughness
ParamUIDesc(
PB_ROUGH,
EDITTYPE_FLOAT,
IDC_MODNOISE_ROUGHNESS,IDC_MODNOISE_ROUGHNESSSPIN,
0.0f,1.0f,
0.005f),
// Iterations
ParamUIDesc(
PB_ITERATIONS,
EDITTYPE_FLOAT,
IDC_MODNOISE_ITERATIONS,IDC_MODNOISE_ITERATIONSSPIN,
1.0f,10.0f,
0.01f),
// Animate
ParamUIDesc(PB_ANIMATE,TYPE_SINGLECHEKBOX,IDC_MODNOISE_ANIMATE),
// Frequency
ParamUIDesc(
PB_FREQ,
EDITTYPE_FLOAT,
IDC_MODNOISE_FREQ,IDC_MODNOISE_FREQSPIN,
0.00001f,BIGFLOAT,
0.01f),
// Phase
ParamUIDesc(
PB_PHASE,
EDITTYPE_TIME,
IDC_MODNOISE_PHASE,IDC_MODNOISE_PHASESPIN,
(float)-999999999,(float)999999999,
10.0f),
// Strength
ParamUIDesc(
PB_STRENGTH,
EDITTYPE_UNIVERSE,
IDC_MODNOISE_XSTRENGTH,IDC_MODNOISE_XSTRENGTHSPIN,
IDC_MODNOISE_YSTRENGTH,IDC_MODNOISE_YSTRENGTHSPIN,
IDC_MODNOISE_ZSTRENGTH,IDC_MODNOISE_ZSTRENGTHSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
};
#define PARAMDESC_LENGH 9
static ParamBlockDescID descVer0[] = {
{ TYPE_INT, NULL, TRUE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_INT, NULL, TRUE, 2 },
{ TYPE_FLOAT, NULL, TRUE, 3 },
{ TYPE_INT, NULL, FALSE, 4 },
{ TYPE_FLOAT, NULL, FALSE, 5 },
{ TYPE_POINT3, NULL, TRUE, 6 } };
static ParamBlockDescID descVer1[] = {
{ TYPE_INT, NULL, TRUE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_INT, NULL, TRUE, 2 },
{ TYPE_FLOAT, NULL, TRUE, 3 },
{ TYPE_FLOAT, NULL, TRUE, 7 },
{ TYPE_INT, NULL, FALSE, 4 },
{ TYPE_FLOAT, NULL, FALSE, 5 },
{ TYPE_INT, NULL, TRUE, 8 },
{ TYPE_POINT3, NULL, TRUE, 6 } };
#define PBLOCK_LENGTH 9
// Array of old versions
static ParamVersionDesc versions[] = {
ParamVersionDesc(descVer0,7,0)
};
#define NUM_OLDVERSIONS 1
// Current version
#define CURRENT_VERSION 1
static ParamVersionDesc curVersion(descVer1,PBLOCK_LENGTH,CURRENT_VERSION);
//--- NoiseDlgProc -------------------------------
class NoiseDlgProc : public ParamMapUserDlgProc {
public:
BOOL DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
void SetState(HWND hWnd);
void DeleteThis() {}
};
static NoiseDlgProc theNoiseProc;
void NoiseDlgProc::SetState(HWND hWnd)
{
ISpinnerControl *spin1 = GetISpinner(GetDlgItem(hWnd,IDC_MODNOISE_ROUGHNESSSPIN));
ISpinnerControl *spin2 = GetISpinner(GetDlgItem(hWnd,IDC_MODNOISE_ITERATIONSSPIN));
if (IsDlgButtonChecked(hWnd,IDC_MODNOISE_FRACTAL)) {
spin1->Enable();
spin2->Enable();
EnableWindow(GetDlgItem(hWnd,IDC_MODNOISE_ROUGHNESSLABEL),TRUE);
EnableWindow(GetDlgItem(hWnd,IDC_MODNOISE_ITERATIONSLABEL),TRUE);
} else {
spin1->Disable();
spin2->Disable();
EnableWindow(GetDlgItem(hWnd,IDC_MODNOISE_ROUGHNESSLABEL),FALSE);
EnableWindow(GetDlgItem(hWnd,IDC_MODNOISE_ITERATIONSLABEL),FALSE);
}
ReleaseISpinner(spin1);
ReleaseISpinner(spin2);
}
BOOL NoiseDlgProc::DlgProc(
TimeValue t,IParamMap *map,
HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
SetState(hWnd);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_MODNOISE_FRACTAL:
SetState(hWnd);
break;
}
break;
}
return FALSE;
}
//--- Noise methods -------------------------------
NoiseMod::NoiseMod() : SimpleMod()
{
MakeRefByID(FOREVER, SIMPMOD_PBLOCKREF,
CreateParameterBlock(descVer1, PBLOCK_LENGTH, CURRENT_VERSION));
pblock->SetValue(PB_SCALE,0,100.0f);
pblock->SetValue(PB_FRACTAL,0,0);
pblock->SetValue(PB_FREQ,0,0.25f);
pblock->SetValue(PB_ITERATIONS,0,6.0f);
SuspendAnimate();
AnimateOn();
pblock->SetValue(PB_PHASE,GetAnimStart(),GetAnimStart());
pblock->SetValue(PB_PHASE,GetAnimEnd(),GetAnimEnd());
ResumeAnimate();
}
IOResult NoiseMod::Load(ILoad *iload)
{
Modifier::Load(iload);
iload->RegisterPostLoadCallback(
new ParamBlockPLCB(versions,NUM_OLDVERSIONS,&curVersion,this,SIMPMOD_PBLOCKREF));
return IO_OK;
}
void NoiseMod::BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev )
{
SimpleMod::BeginEditParams(ip,flags,prev);
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_NOISEPARAM),
GetString(IDS_RB_PARAMETERS),
0);
pmapParam->SetUserDlgProc(&theNoiseProc);
}
void NoiseMod::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
{
SimpleMod::EndEditParams(ip,flags,next);
DestroyCPParamMap(pmapParam);
}
Interval NoiseMod::GetValidity(TimeValue t)
{
float f;
int i, animate;
Point3 p;
Interval valid = FOREVER;
pblock->GetValue(PB_SEED,t,i,valid);
pblock->GetValue(PB_SCALE,t,f,valid);
pblock->GetValue(PB_FRACTAL,t,i,valid);
pblock->GetValue(PB_ROUGH,t,f,valid);
pblock->GetValue(PB_ITERATIONS,t,f,valid);
pblock->GetValue(PB_ANIMATE,t,animate,valid);
pblock->GetValue(PB_FREQ,t,f,valid);
pblock->GetValue(PB_STRENGTH,t,p,valid);
if (animate) pblock->GetValue(PB_PHASE,t,i,valid);
if (animate) valid.SetInstant(t);
return valid;
}
RefTargetHandle NoiseMod::Clone(RemapDir& remap)
{
NoiseMod* newmod = new NoiseMod();
newmod->ReplaceReference(SIMPMOD_PBLOCKREF,pblock->Clone(remap));
newmod->SimpleModClone(this);
return(newmod);
}
NoiseDeformer::NoiseDeformer()
{
tm.IdentityMatrix();
invtm.IdentityMatrix();
}
Point3 NoiseDeformer::Map(int i, Point3 p)
{
Point3 d, sp;
p = p * tm;
sp = p * scale + Point3(0.5f,0.5f,0.5f);
if (fractal) {
d.x = fBm1(Point3(sp.y,sp.z,time),rough,2.0f,iterations);
d.y = fBm1(Point3(sp.x,sp.z,time),rough,2.0f,iterations);
d.z = fBm1(Point3(sp.x,sp.y,time),rough,2.0f,iterations);
} else {
d.x = noise3(Point3(sp.y,sp.z,time));
d.y = noise3(Point3(sp.x,sp.z,time));
d.z = noise3(Point3(sp.x,sp.y,time));
}
return (p+(d*strength)) * invtm;
}
NoiseDeformer::NoiseDeformer(
ModContext &mc,
TimeValue t,
int seed, float scale, int fractal, float iterations,
float rough, int anim, float freq,
Point3 strength,
TimeValue phase,
Matrix3& modmat, Matrix3& modinv)
{
tm = modmat;
invtm = modinv;
this->scale = (scale==0.0f) ? 0.00001f : (1.0f/scale);
this->fractal = fractal;
this->rough = 1.0f-rough;
this->strength = strength;
this->iterations = iterations;
if (anim) {
time = float(phase) * float(0.005) * freq *
1200.0f/float(TIME_TICKSPERSEC) + Perm(seed);
} else {
time = (float)Perm(seed);
}
}
Deformer& NoiseMod::GetDeformer(
TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
{
int fractal, seed, anim;
float scale, rough, freq, iterations;
TimeValue phase;
Point3 strength;
pblock->GetValue(PB_SEED,t,seed,FOREVER);
pblock->GetValue(PB_SCALE,t,scale,FOREVER);
pblock->GetValue(PB_FRACTAL,t,fractal,FOREVER);
pblock->GetValue(PB_ITERATIONS,t,iterations,FOREVER);
pblock->GetValue(PB_ROUGH,t,rough,FOREVER);
pblock->GetValue(PB_ANIMATE,t,anim,FOREVER);
pblock->GetValue(PB_FREQ,t,freq,FOREVER);
pblock->GetValue(PB_PHASE,t,phase,FOREVER);
pblock->GetValue(PB_STRENGTH,t,strength,FOREVER);
if (iterations<1.0f) iterations = 1.0f;
if (scale<0.00001f) scale = 0.00001f;
static NoiseDeformer deformer;
deformer = NoiseDeformer(mc,t,seed,scale,fractal,iterations,rough,anim,freq,strength,phase,mat,invmat);
return deformer;
}
ParamDimension *NoiseMod::GetParameterDim(int pbIndex)
{
switch (pbIndex) {
case PB_SEED: return defaultDim;
case PB_SCALE: return defaultDim;
case PB_FRACTAL: return defaultDim;
case PB_ROUGH: return defaultDim;
case PB_STRENGTH: return stdWorldDim;
case PB_PHASE: return stdTimeDim;
case PB_ITERATIONS: return defaultDim;
default: return defaultDim;
}
}
TSTR NoiseMod::GetParameterName(int pbIndex)
{
switch (pbIndex) {
case PB_SEED: return GetString(IDS_RB_SEED);
case PB_SCALE: return GetString(IDS_RB_SCALE);
case PB_FRACTAL: return GetString(IDS_RB_FRACTAL);
case PB_ROUGH: return GetString(IDS_RB_ROUGH);
case PB_STRENGTH: return GetString(IDS_RB_STRENGTH2);
case PB_PHASE: return GetString(IDS_RB_PHASE);
case PB_ITERATIONS: return GetString(IDS_RB_ITERATIONS);
default: return TSTR(_T(""));
}
}
@@ -0,0 +1,567 @@
/**********************************************************************
*<
FILE: optmod.cpp
DESCRIPTION: Optimize modifier
CREATED BY: Rolf Berteig
HISTORY: 10/20/95
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
class OptMod : public Modifier, public MeshOpProgress {
public:
IParamBlock *pblock;
static IParamMap *pmapParam;
BOOL forceUpdate;
OptMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) { s= GetString(IDS_RB_OPTMOD); }
virtual Class_ID ClassID() { return Class_ID(OPTIMIZEOSM_CLASS_ID,0);}
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams( IObjParam *ip,ULONG flags,Animatable *next);
TCHAR *GetObjectName() { return GetString(IDS_RB_OPTIMIZE); }
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
int RenderBegin(TimeValue t, ULONG flags);
int RenderEnd(TimeValue t);
IOResult Load(ILoad *iload);
ChannelMask ChannelsUsed() {return OBJ_CHANNELS;}
ChannelMask ChannelsChanged() {return OBJ_CHANNELS;}
Class_ID InputType() {return triObjectClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t);
int NumRefs() {return 1;}
RefTargetHandle GetReference(int i) {return pblock;}
void SetReference(int i, RefTargetHandle rtarg) {pblock = (IParamBlock*)rtarg;}
int NumSubs() {return 1;}
Animatable* SubAnim(int i) {return pblock;}
TSTR SubAnimName(int i) {return GetString(IDS_RB_PARAMETERS);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
// From MeshOpProgress
void Init(int total);
BOOL Progress(int p);
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *OptMod::pmapParam = NULL;
class OptClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new OptMod; }
const TCHAR * ClassName() { return GetString(IDS_RB_OPTIMIZE_CLASS); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(OPTIMIZEOSM_CLASS_ID,0); }
const TCHAR* Category() { return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static OptClassDesc optDesc;
extern ClassDesc* GetOptModDesc() { return &optDesc; }
//--- Parameter map/block descriptors -------------------------------
#define A_RENDER A_PLUGIN1
#define PB_RENDER 0
#define PB_VIEWS 1
#define PB_FACETHRESH1 2
#define PB_EDGETHRESH1 3
#define PB_BIAS1 4
#define PB_PRESERVEMAT1 5
#define PB_PRESERVESMOOTH1 6
#define PB_MAXEDGE1 7
#define PB_FACETHRESH2 8
#define PB_EDGETHRESH2 9
#define PB_BIAS2 10
#define PB_PRESERVEMAT2 11
#define PB_PRESERVESMOOTH2 12
#define PB_MAXEDGE2 13
#define PB_AUTOEDGE 14
#define PB_MANUPDATE 15
// Map indices
#define MAP_FACETHRESH 2
#define MAP_EDGETHRESH 3
#define MAP_BIAS 4
#define MAP_PRESERVEMAT 5
#define MAP_PRESERVESMOOTH 6
#define MAP_MAXEDGE 7
//
//
// Parameters
static int renderIDs[] = {IDC_OPT_RENDERL1,IDC_OPT_RENDERL2};
static int viewsIDs[] = {IDC_OPT_VIEWSL1,IDC_OPT_VIEWSL2};
static ParamUIDesc descParam[] = {
// Renderer
ParamUIDesc(PB_RENDER,TYPE_RADIO,renderIDs,2),
// Viewports
ParamUIDesc(PB_VIEWS,TYPE_RADIO,viewsIDs,2),
// Face thresh
ParamUIDesc(
PB_FACETHRESH1,
EDITTYPE_FLOAT,
IDC_OPT_FACETHRESH,IDC_OPT_FACETHRESHSPIN,
0.0f,90.0f,
0.1f,
stdAngleDim),
// Edge thresh
ParamUIDesc(
PB_EDGETHRESH1,
EDITTYPE_FLOAT,
IDC_OPT_EDGETHRESH,IDC_OPT_EDGETHRESHSPIN,
0.0f,90.0f,
0.1f,
stdAngleDim),
// Bias
ParamUIDesc(
PB_BIAS1,
EDITTYPE_FLOAT,
IDC_OPT_BIAS,IDC_OPT_BIASSPIN,
0.0f,1.0f,
0.01f),
// Preserve mat boundries
ParamUIDesc(PB_PRESERVEMAT1,TYPE_SINGLECHEKBOX,IDC_OPT_PRESERVEMAT),
// Preserve smooth boundries
ParamUIDesc(PB_PRESERVESMOOTH1,TYPE_SINGLECHEKBOX,IDC_OPT_PRESERVESMOOTH),
// Max Edge
ParamUIDesc(
PB_MAXEDGE1,
EDITTYPE_FLOAT,
IDC_OPT_MAXEDGE,IDC_OPT_MAXEDGESPIN,
0.0f,BIGFLOAT,
SPIN_AUTOSCALE),
// Auto edge
ParamUIDesc(PB_AUTOEDGE,TYPE_SINGLECHEKBOX,IDC_OPT_AUTOEDGE),
// Manual update
ParamUIDesc(PB_MANUPDATE,TYPE_SINGLECHEKBOX,IDC_OPT_MANUPDATE),
};
#define PARAMDESC_LENGH 10
static ParamBlockDescID descVer0[] = {
{ TYPE_INT, NULL, FALSE, 0 },
{ TYPE_INT, NULL, FALSE, 1 },
{ TYPE_FLOAT, NULL, TRUE, 2 },
{ TYPE_FLOAT, NULL, TRUE, 3 },
{ TYPE_FLOAT, NULL, TRUE, 4 },
{ TYPE_INT, NULL, FALSE, 5 },
{ TYPE_INT, NULL, FALSE, 6 },
{ TYPE_FLOAT, NULL, TRUE, 7 },
{ TYPE_FLOAT, NULL, TRUE, 8 },
{ TYPE_FLOAT, NULL, TRUE, 9 },
{ TYPE_INT, NULL, FALSE, 10 },
{ TYPE_INT, NULL, FALSE, 11 },
{ TYPE_INT, NULL, FALSE, 12 } };
static ParamBlockDescID descVer1[] = {
{ TYPE_INT, NULL, FALSE, 0 },
{ TYPE_INT, NULL, FALSE, 1 },
{ TYPE_FLOAT, NULL, TRUE, 2 },
{ TYPE_FLOAT, NULL, TRUE, 3 },
{ TYPE_FLOAT, NULL, TRUE, 4 },
{ TYPE_INT, NULL, FALSE, 5 },
{ TYPE_INT, NULL, FALSE, 6 },
{ TYPE_FLOAT, NULL, TRUE, 13 }, // max edge1
{ TYPE_FLOAT, NULL, TRUE, 7 },
{ TYPE_FLOAT, NULL, TRUE, 8 },
{ TYPE_FLOAT, NULL, TRUE, 9 },
{ TYPE_INT, NULL, FALSE, 10 },
{ TYPE_INT, NULL, FALSE, 11 },
{ TYPE_FLOAT, NULL, TRUE, 14 }, // max edge2
{ TYPE_INT, NULL, FALSE, 12 },
};
static ParamBlockDescID descVer2[] = {
{ TYPE_INT, NULL, FALSE, 0 },
{ TYPE_INT, NULL, FALSE, 1 },
{ TYPE_FLOAT, NULL, TRUE, 2 },
{ TYPE_FLOAT, NULL, TRUE, 3 },
{ TYPE_FLOAT, NULL, TRUE, 4 },
{ TYPE_INT, NULL, FALSE, 5 },
{ TYPE_INT, NULL, FALSE, 6 },
{ TYPE_FLOAT, NULL, TRUE, 13 }, // max edge1
{ TYPE_FLOAT, NULL, TRUE, 7 },
{ TYPE_FLOAT, NULL, TRUE, 8 },
{ TYPE_FLOAT, NULL, TRUE, 9 },
{ TYPE_INT, NULL, FALSE, 10 },
{ TYPE_INT, NULL, FALSE, 11 },
{ TYPE_FLOAT, NULL, TRUE, 14 }, // max edge2
{ TYPE_INT, NULL, FALSE, 12 },
{ TYPE_INT, NULL, FALSE, 15 },
};
#define PBLOCK_LENGTH 16
// Array of old versions
static ParamVersionDesc versions[] = {
ParamVersionDesc(descVer0,13,0),
ParamVersionDesc(descVer1,15,0)
};
#define NUM_OLDVERSIONS 2
// Current version
#define CURRENT_VERSION 2
static ParamVersionDesc curVersion(descVer2,PBLOCK_LENGTH,CURRENT_VERSION);
//--- OptDlgProc -------------------------------
class OptDlgProc : public ParamMapUserDlgProc {
public:
Interface *ip;
OptMod *mod;
OptDlgProc() {ip=NULL;mod=NULL;}
BOOL DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
void SetupLevels(IParamMap *map);
void SetupManButton(HWND hWnd,IParamMap *map);
void DeleteThis() {}
};
static OptDlgProc theOptProc;
void OptDlgProc::SetupLevels(IParamMap *map)
{
int l;
map->GetParamBlock()->GetValue(PB_VIEWS,0,l,FOREVER);
if (l==0) {
map->SetPBlockIndex(MAP_FACETHRESH,PB_FACETHRESH1);
map->SetPBlockIndex(MAP_EDGETHRESH,PB_EDGETHRESH1);
map->SetPBlockIndex(MAP_BIAS,PB_BIAS1);
map->SetPBlockIndex(MAP_PRESERVEMAT,PB_PRESERVEMAT1);
map->SetPBlockIndex(MAP_PRESERVESMOOTH,PB_PRESERVESMOOTH1);
map->SetPBlockIndex(MAP_MAXEDGE,PB_MAXEDGE1);
} else {
map->SetPBlockIndex(MAP_FACETHRESH,PB_FACETHRESH2);
map->SetPBlockIndex(MAP_EDGETHRESH,PB_EDGETHRESH2);
map->SetPBlockIndex(MAP_BIAS,PB_BIAS2);
map->SetPBlockIndex(MAP_PRESERVEMAT,PB_PRESERVEMAT2);
map->SetPBlockIndex(MAP_PRESERVESMOOTH,PB_PRESERVESMOOTH2);
map->SetPBlockIndex(MAP_MAXEDGE,PB_MAXEDGE2);
}
}
void OptDlgProc::SetupManButton(HWND hWnd,IParamMap *map)
{
int man;
map->GetParamBlock()->GetValue(PB_MANUPDATE,0,man,FOREVER);
EnableWindow(GetDlgItem(hWnd,IDC_OPT_UPDATE),man);
}
BOOL OptDlgProc::DlgProc(
TimeValue t,IParamMap *map,
HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
SetupLevels(map);
SetWindowText(GetDlgItem(hWnd,IDC_OPT_VERTCOUNT),NULL);
SetWindowText(GetDlgItem(hWnd,IDC_OPT_FACECOUNT),NULL);
SetupManButton(hWnd,map);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_OPT_VIEWSL1:
case IDC_OPT_VIEWSL2:
SetupLevels(map);
break;
case IDC_OPT_MANUPDATE:
SetupManButton(hWnd,map);
break;
case IDC_OPT_UPDATE:
mod->forceUpdate = TRUE;
mod->NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
ip->RedrawViews(ip->GetTime());
break;
}
break;
}
return FALSE;
}
//--- Opt methods -------------------------------
OptMod::OptMod()
{
MakeRefByID(FOREVER, 0,
CreateParameterBlock(descVer2, PBLOCK_LENGTH, CURRENT_VERSION));
pblock->SetValue(PB_FACETHRESH1,0,DegToRad(4.0f));
pblock->SetValue(PB_EDGETHRESH1,0,DegToRad(1.0f));
pblock->SetValue(PB_BIAS1,0,0.1f);
pblock->SetValue(PB_FACETHRESH2,0,DegToRad(4.0f));
pblock->SetValue(PB_EDGETHRESH2,0,DegToRad(1.0f));
pblock->SetValue(PB_BIAS2,0,0.1f);
pblock->SetValue(PB_MANUPDATE,0,0);
forceUpdate = FALSE;
}
IOResult OptMod::Load(ILoad *iload)
{
Modifier::Load(iload);
iload->RegisterPostLoadCallback(
new ParamBlockPLCB(versions,NUM_OLDVERSIONS,&curVersion,this,0));
return IO_OK;
}
void OptMod::BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev)
{
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_OPTIMIZEPARAM),
GetString(IDS_RB_PARAMETERS),
0);
theOptProc.ip = ip;
theOptProc.mod = this;
pmapParam->SetUserDlgProc(&theOptProc);
}
void OptMod::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
{
DestroyCPParamMap(pmapParam);
pmapParam = NULL;
theOptProc.ip = NULL;
theOptProc.mod = NULL;
}
Interval OptMod::LocalValidity(TimeValue t)
{
float f;
Interval valid = FOREVER;
int man;
pblock->GetValue(PB_MANUPDATE,t,man,valid);
if (!man) {
pblock->GetValue(PB_FACETHRESH1,t,f,valid);
pblock->GetValue(PB_EDGETHRESH1,t,f,valid);
pblock->GetValue(PB_BIAS1,t,f,valid);
pblock->GetValue(PB_MAXEDGE1,t,f,valid);
pblock->GetValue(PB_FACETHRESH2,t,f,valid);
pblock->GetValue(PB_EDGETHRESH2,t,f,valid);
pblock->GetValue(PB_BIAS2,t,f,valid);
pblock->GetValue(PB_MAXEDGE2,t,f,valid);
}
return valid;
}
RefTargetHandle OptMod::Clone(RemapDir& remap)
{
OptMod* newmod = new OptMod();
newmod->ReplaceReference(0,pblock->Clone(remap));
return newmod;
}
int OptMod::RenderBegin(TimeValue t, ULONG flags)
{
int views, render, man;
pblock->GetValue(PB_VIEWS,0,views,FOREVER);
pblock->GetValue(PB_RENDER,0,render,FOREVER);
pblock->GetValue(PB_MANUPDATE,0,man,FOREVER);
SetAFlag(A_RENDER);
if (views!=render || man) {
NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
}
return 0;
}
int OptMod::RenderEnd(TimeValue t)
{
int views, render;
pblock->GetValue(PB_VIEWS,0,views,FOREVER);
pblock->GetValue(PB_RENDER,0,render,FOREVER);
ClearAFlag(A_RENDER);
if (views!=render) {
NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
}
return 0;
}
void OptMod::Init(int total)
{
}
BOOL OptMod::Progress(int p)
{
SHORT res = GetAsyncKeyState(VK_ESCAPE);
if (res&1) return FALSE;
else return TRUE;
}
void OptMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
float faceThresh, edgeThresh, bias, maxEdge;
int preserveMat, preserveSmooth, which, render=0, autoEdge;
DWORD flags = 0;
Interval valid = FOREVER;
int nv,nf;
int man;
pblock->GetValue(PB_MANUPDATE,t,man,valid);
if (man && !forceUpdate && !TestAFlag(A_RENDER)) return;
forceUpdate = FALSE;
if (TestAFlag(A_RENDER)) {
pblock->GetValue(PB_RENDER,t,which,valid);
} else {
pblock->GetValue(PB_VIEWS,t,which,valid);
}
pblock->GetValue(PB_AUTOEDGE,t,autoEdge,valid);
if (which==0) {
pblock->GetValue(PB_FACETHRESH1,t,faceThresh,valid);
pblock->GetValue(PB_EDGETHRESH1,t,edgeThresh,valid);
pblock->GetValue(PB_BIAS1,t,bias,valid);
pblock->GetValue(PB_PRESERVEMAT1,t,preserveMat,valid);
pblock->GetValue(PB_PRESERVESMOOTH1,t,preserveSmooth,valid);
pblock->GetValue(PB_MAXEDGE1,t,maxEdge,valid);
} else {
pblock->GetValue(PB_FACETHRESH2,t,faceThresh,valid);
pblock->GetValue(PB_EDGETHRESH2,t,edgeThresh,valid);
pblock->GetValue(PB_BIAS2,t,bias,valid);
pblock->GetValue(PB_PRESERVEMAT2,t,preserveMat,valid);
pblock->GetValue(PB_PRESERVESMOOTH2,t,preserveSmooth,valid);
pblock->GetValue(PB_MAXEDGE2,t,maxEdge,valid);
}
assert(os->obj->IsSubClassOf(triObjectClassID));
TriObject *triOb = (TriObject *)os->obj;
nv = triOb->mesh.getNumVerts();
nf = triOb->mesh.getNumFaces();
if (preserveMat) flags |= OPTIMIZE_SAVEMATBOUNDRIES;
if (preserveSmooth) flags |= OPTIMIZE_SAVESMOOTHBOUNDRIES;
if (autoEdge) flags |= OPTIMIZE_AUTOEDGE;
if (faceThresh!=0.0f) {
GetAsyncKeyState(VK_ESCAPE); // clear the state
HCURSOR hCur;
if (nf > 2000) hCur = SetCursor(LoadCursor(NULL,IDC_WAIT));
triOb->mesh.Optimize(
faceThresh,edgeThresh, bias*0.5f, maxEdge, flags,this);
if (nf > 200) SetCursor(hCur);
}
triOb->PointsWereChanged();
triOb->UpdateValidity(GEOM_CHAN_NUM,valid);
triOb->UpdateValidity(TOPO_CHAN_NUM,valid);
if (pmapParam && pmapParam->GetParamBlock()==pblock && !TestAFlag(A_RENDER)) {
TSTR buf;
buf.printf("%d / %d",nv,triOb->mesh.getNumVerts());
SetWindowText(GetDlgItem(pmapParam->GetHWnd(),IDC_OPT_VERTCOUNT),buf);
buf.printf("%d / %d",nf,triOb->mesh.getNumFaces());
SetWindowText(GetDlgItem(pmapParam->GetHWnd(),IDC_OPT_FACECOUNT),buf);
}
}
RefResult OptMod::NotifyRefChanged(
Interval changeInt,
RefTargetHandle hTarget,
PartID& partID,
RefMessage message)
{
switch (message) {
case REFMSG_CHANGE: {
if (pmapParam && pmapParam->GetParamBlock()==pblock) {
pmapParam->Invalidate();
}
int man = FALSE;
if (pblock) pblock->GetValue(PB_MANUPDATE,0,man,FOREVER);
if (man) return REF_STOP;
break;
}
case REFMSG_GET_PARAM_DIM: {
GetParamDim *gpd = (GetParamDim*)partID;
switch (gpd->index) {
case PB_FACETHRESH1:
case PB_FACETHRESH2:
case PB_EDGETHRESH1:
case PB_EDGETHRESH2: gpd->dim = stdAngleDim; break;
case PB_MAXEDGE1:
case PB_MAXEDGE2: gpd->dim = stdWorldDim; break;
default: gpd->dim = defaultDim; break;
}
return REF_STOP;
}
case REFMSG_GET_PARAM_NAME: {
GetParamName *gpn = (GetParamName*)partID;
switch (gpn->index) {
case PB_FACETHRESH1: gpn->name = GetString(IDS_RB_FACETHRESHL1); break;
case PB_FACETHRESH2: gpn->name = GetString(IDS_RB_FACETHRESHL2); break;
case PB_EDGETHRESH1: gpn->name = GetString(IDS_RB_EDGETHRESHL1); break;
case PB_EDGETHRESH2: gpn->name = GetString(IDS_RB_EDGETHRESHL2); break;
case PB_BIAS1: gpn->name = GetString(IDS_RB_BIASL1); break;
case PB_BIAS2: gpn->name = GetString(IDS_RB_BIASL2); break;
case PB_MAXEDGE1: gpn->name = GetString(IDS_RB_MAXEDGE1); break;
case PB_MAXEDGE2: gpn->name = GetString(IDS_RB_MAXEDGE2); break;
default: gpn->name = TSTR(_T("")); break;
}
return REF_STOP;
}
}
return REF_SUCCEED;
}
@@ -0,0 +1,233 @@
/**********************************************************************
*<
FILE: resettm.cpp
DESCRIPTION: A reset xform utility
CREATED BY: Rolf Berteig
HISTORY: created June 28, 1996
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "utilapi.h"
#include "istdplug.h"
#include "modstack.h"
#include "simpmod.h"
#include "dummy.h"
#include "decomp.h"
#include "matrix3.h"
#define RESET_XFORM_CLASS_ID_2 Class_ID(0x2eac7e3f, 0x46bf2cc8)
class ResetXForm : public UtilityObj {
public:
IUtil *iu;
Interface *ip;
HWND hPanel;
ResetXForm();
void BeginEditParams(Interface *ip,IUtil *iu);
void EndEditParams(Interface *ip,IUtil *iu);
void SelectionSetChanged(Interface *ip,IUtil *iu);
void DeleteThis() {}
void ResetSel();
};
static ResetXForm theResetXForm;
class ResetXFormClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE) {return &theResetXForm;}
const TCHAR * ClassName() {return GetString(IDS_RB_RESETXFORM_CLASS);}
SClass_ID SuperClassID() {return UTILITY_CLASS_ID;}
Class_ID ClassID() {return RESET_XFORM_CLASS_ID_2;}
const TCHAR* Category() {return _T("");}
};
static ResetXFormClassDesc resetXFormDesc;
ClassDesc* GetResetXFormDesc() {return &resetXFormDesc;}
static BOOL CALLBACK ResetXFormDlgProc(
HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
theResetXForm.hPanel = hWnd;
theResetXForm.
SelectionSetChanged(theResetXForm.ip,theResetXForm.iu);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
theResetXForm.iu->CloseUtility();
break;
case IDC_RESETTM_SELECTED:
theResetXForm.ResetSel();
break;
}
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
theResetXForm.ip->RollupMouseMessage(hWnd,msg,wParam,lParam);
break;
default:
return FALSE;
}
return TRUE;
}
ResetXForm::ResetXForm()
{
iu = NULL;
ip = NULL;
hPanel = NULL;
}
void ResetXForm::BeginEditParams(Interface *ip,IUtil *iu)
{
this->iu = iu;
this->ip = ip;
hPanel = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_RESETXFORM_PANEL),
ResetXFormDlgProc,
GetString(IDS_RB_RESETXFORM),
0);
}
void ResetXForm::EndEditParams(Interface *ip,IUtil *iu)
{
this->iu = NULL;
this->ip = NULL;
ip->DeleteRollupPage(hPanel);
hPanel = NULL;
}
void ResetXForm::SelectionSetChanged(Interface *ip,IUtil *iu)
{
if (ip->GetSelNodeCount()) {
BOOL res = FALSE;
for (int i=0; i<ip->GetSelNodeCount(); i++) {
INode *node = ip->GetSelNode(i);
if (!node->IsGroupMember() && !node->IsGroupHead()) {
res = TRUE;
break;
}
}
EnableWindow(GetDlgItem(hPanel,IDC_RESETTM_SELECTED),res);
} else {
EnableWindow(GetDlgItem(hPanel,IDC_RESETTM_SELECTED),FALSE);
}
}
static BOOL SelectedAncestor(INode *node)
{
if (!node->GetParentNode()) return FALSE;
if (node->GetParentNode()->Selected()) return TRUE;
else return SelectedAncestor(node->GetParentNode());
}
void ResetXForm::ResetSel()
{
//theHold.Begin();
for (int i=0; i<ip->GetSelNodeCount(); i++) {
INode *node = ip->GetSelNode(i);
if (node->IsGroupMember() || node->IsGroupHead()) continue;
if (SelectedAncestor(node)) continue;
Matrix3 ntm, ptm, rtm(1), piv(1), tm;
// Get Parent and Node TMs
ntm = node->GetNodeTM(ip->GetTime());
ptm = node->GetParentTM(ip->GetTime());
// Compute the relative TM
ntm = ntm * Inverse(ptm);
// if it is a dummy object...
ObjectState os;
os = node->EvalWorldState(ip->GetTime());
if (os.obj)
{
if (os.obj->ClassID() == Class_ID(DUMMY_CLASS_ID,0))
{
DummyObject* dummy = (DummyObject*)os.obj;
Box3 bound_box;
bound_box = dummy->GetBox();
// apply scale...
Matrix3 scale_matrix;
scale_matrix.IdentityMatrix();
AffineParts parts;
decomp_affine(ntm, &parts);
scale_matrix = ScaleMatrix(parts.k);
Box3 new_box;
new_box = bound_box * scale_matrix;
dummy->SetBox(new_box);
}
}
// The reset TM only inherits position
rtm.SetTrans(ntm.GetTrans());
// Set the node TM to the reset TM
tm = rtm*ptm;
node->SetNodeTM(ip->GetTime(), tm);
// Compute the pivot TM
piv.SetTrans(node->GetObjOffsetPos());
PreRotateMatrix(piv,node->GetObjOffsetRot());
ApplyScaling(piv,node->GetObjOffsetScale());
// Reset the offset to 0
node->SetObjOffsetPos(Point3(0,0,0));
node->SetObjOffsetRot(IdentQuat());
node->SetObjOffsetScale(ScaleValue(Point3(1,1,1)));
// Take the position out of the matrix since we don't reset position
ntm.NoTrans();
// Apply the offset to the TM
ntm = piv * ntm;
// Apply a derived object to the node's object
Object *obj = node->GetObjectRef();
IDerivedObject *dobj = CreateDerivedObject(obj);
// Create an XForm mod
SimpleMod *mod = (SimpleMod*)ip->CreateInstance(
OSM_CLASS_ID,
Class_ID(CLUSTOSM_CLASS_ID,0));
// Apply the transformation to the mod.
SetXFormPacket pckt(ntm);
mod->tmControl->SetValue(ip->GetTime(),&pckt);
// Add the bend modifier to the derived object.
dobj->AddModifier(mod);
// Replace the node's object
node->SetObjectRef(dobj);
}
//theHold.Accept(GetString(IDS_RB_RESETXFORM));
GetSystemSetting(SYSSET_CLEAR_UNDO);
ip->RedrawViews(ip->GetTime());
}
@@ -0,0 +1,107 @@
/**********************************************************************
*<
FILE: sctex.cpp
DESCRIPTION: A ShadeContext for rendering texture maps
CREATED BY: Rolf Berteig (took code from mtlrend.cpp
HISTORY: 2/02/96
*> Copyright (c) 1996, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "sctex.h"
#include "gamma.h"
SCTex::SCTex() {
tiling = 1.0f;
mtlNum = 0;
doMaps = TRUE;
filterMaps = TRUE;
shadow = FALSE;
backFace = FALSE;
curTime = 0;
norm = Point3(0,0,1);
view = Point3(0,0,-1);
ResetOutput();
}
Box3 SCTex::ObjectBox() {
return Box3(Point3(0,0,0),Point3(scale,scale,scale));
}
Point3 SCTex::PObjRelBox() {
Point3 q;
Point3 p = PObj();
Box3 b = ObjectBox();
q.x = 2.0f*(p.x-b.pmin.x)/(b.pmax.x-b.pmin.x) - 1.0f;
q.y = 2.0f*(p.y-b.pmin.y)/(b.pmax.y-b.pmin.y) - 1.0f;
q.z = 2.0f*(p.z-b.pmin.z)/(b.pmax.z-b.pmin.z) - 1.0f;
return q;
}
void SCTex::ScreenUV(Point2& uv, Point2 &duv) {
uv.x = uvw.x;
uv.y = uvw.x;
duv.x = duvw.x;
duv.y = duvw.y;
}
Point3 SCTex::DPObjRelBox() {
return Point3(0,0,0);
}
// Bump vectors for UVW: in Camera space
void SCTex::DPdUVW(Point3 dP[3],int chan) {
dP[0] = dP[1] = dP[2] = Point3(0,0,0);
}
Point3 SCTex::P() {
return pt;
}
Point3 SCTex::DP() {
return dpt;
}
Point3 SCTex::PObj() {
return pt;
}
Point3 SCTex::DPObj() {
return dpt;
}
UBYTE *RenderTexMap(Texmap *tex,int w, int h)
{
float du = 1.0f/float(w);
float dv = 1.0f/float(h);
AColor col;
SCTex sc;
int scanw = ByteWidth(w*3);
UBYTE *image = new UBYTE[ByteWidth(w*3)*h];
UBYTE *p1;
sc.scale = 1.0f;
sc.duvw = Point3(du,dv,0.0f);
sc.dpt = sc.duvw;
sc.uvw.y = 1.0f-0.5f*dv;
for (int j=0; j<h; j++) {
sc.scrPos.y = j;
sc.uvw.x = 0.5f*du;
p1 = image + (h-j-1)*scanw;
for (int i=0; i<w; i++) {
sc.scrPos.x = i;
sc.pt = sc.uvw;
col = tex->EvalColor(sc);
*p1++ = gammaCorrect((UBYTE)(col.b*255.0f));
*p1++ = gammaCorrect((UBYTE)(col.g*255.0f));
*p1++ = gammaCorrect((UBYTE)(col.r*255.0f));
sc.uvw.x +=du;
}
sc.uvw.y -= dv;
}
return image;
}
@@ -0,0 +1,82 @@
/**********************************************************************
*<
FILE: sctex.h
DESCRIPTION: A ShadeContext for rendering texture maps
CREATED BY: Rolf Berteig (took code from mtlrend.cpp
HISTORY: 2/02/96
*> Copyright (c) 1996, All Rights Reserved.
**********************************************************************/
#ifndef __SCTEXT_H__
#define __SCTEXT_H__
class LightDescImp: public LightDesc {
public:
Point3 pos;
Color col;
BOOL Illuminate(ShadeContext& sc, Point3& normal, Color& color, Point3 &dir, float &dot_nl) {
dir = Normalize(pos-sc.P());
dot_nl = DotProd(normal,dir);
color = col;
return 1;
}
};
class SCTex: public ShadeContext {
public:
float tiling;
float scale;
Color ambientLight;
LightDescImp* lights[2];
Point3 uvw,duvw,norm,view,pt,dpt;
IPoint2 scrPos;
TimeValue curTime;
Renderer *GetRenderer() { return NULL; }
BOOL InMtlEditor() { return TRUE; }
LightDesc* Light(int n) { return lights[n]; }
int ProjType() { return 1;} // returns: 0: perspective, 1: parallel
int FaceNumber() { return 0; }
TimeValue CurTime() { return curTime; }
Point3 Normal() { return norm; } // interpolated normal
void SetNormal(Point3 p) { norm = p;} // for perturbing normal
Point3 GNormal() { return norm;} // geometric (face) normal
Point3 ReflectVector() { return Point3(0,0,1); }
Point3 RefractVector(float ior) {return Point3(0,0,1); }
Point3 CamPos() { return Point3(0,0,0); } // camera position
Point3 V() { return view; } // Unit view vector: from camera towards P
void SetView(Point3 v) { view =v; }
Point3 P(); // point to be shaded in camera space;
Point3 DP(); // deriv of P, relative to pixel, for AA
Point3 PObj(); // point in obj coords
Point3 DPObj(); // deriv of PObj, rel to pixel, for AA
Box3 ObjectBox(); // Object extents box in obj coords
Point3 PObjRelBox(); // Point rel to obj box [-1 .. +1 ]
Point3 DPObjRelBox(); // Point rel to obj box [-1 .. +1 ]
Point3 UVW(int chan) { return uvw; };
Point3 DUVW(int chan) { return duvw; }
void DPdUVW(Point3 dP[3],int chan); // Bump vectors for UVW: in Camera space
AColor EvalEnvironMap(Texmap *map, Point3 viewd) {
AColor rcol;
return rcol;
}
void ScreenUV(Point2& uv, Point2 &duv); // screen coordinate
IPoint2 SCTex::ScreenCoord() {return scrPos;}
Point3 PointTo(const Point3& p, RefFrame ito) { return p; }
Point3 PointFrom(const Point3& p, RefFrame ifrom) { return p; }
Point3 VectorTo(const Point3& p, RefFrame ito) { return p; }
Point3 VectorFrom(const Point3& p, RefFrame ifrom){ return p; }
void GetBGColor(Color &bgcol, Color& transp, BOOL fogBG=TRUE) { }
SCTex();
void SetTiling(float t) { tiling = t; }
};
// Allocates and renders a 3 byte per pixel image
UBYTE *RenderTexMap(Texmap *tex,int w, int h);
#endif //__SCTEXT_H__
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,413 @@
/**********************************************************************
*<
FILE: skew.cpp
DESCRIPTION: Skew Modifier
CREATED BY: Rolf Berteig
HISTORY: created 18 October 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#include "simpmod.h"
#include "simpobj.h"
// in mods.cpp
extern HINSTANCE hInstance;
#define BIGFLOAT float(999999)
class SkewMod : public SimpleMod {
public:
static IParamMap *pmapParam;
SkewMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) { s= GetString(IDS_RB_SKEWMOD); }
virtual Class_ID ClassID() { return Class_ID(SKEWOSM_CLASS_ID,0);}
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams( IObjParam *ip,ULONG flags,Animatable *next);
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() { return GetString(IDS_RB_SKEW); }
IOResult Load(ILoad *iload);
// From simple mod
Deformer& GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat);
Interval GetValidity(TimeValue t);
ParamDimension *GetParameterDim(int pbIndex);
TSTR GetParameterName(int pbIndex);
BOOL GetModLimits(TimeValue t,float &zmin, float &zmax, int &axis);
void InvalidateUI() {if (pmapParam) pmapParam->Invalidate();}
};
class SkewDeformer: public Deformer {
public:
Matrix3 tm,invtm;
Box3 bbox;
float from, to, amountOverLength;
int doRegion;
SkewDeformer();
SkewDeformer(
ModContext &mc,
float amount, float dir, int naxis,
float from, float to, int doRegion,
Matrix3& modmat, Matrix3& modinv);
Point3 Map(int i, Point3 p);
};
#define SKEWWSM_CLASSID Class_ID(SKEWOSM_CLASS_ID,1)
class SkewWSM : public SimpleOSMToWSMObject {
public:
SkewWSM() {}
SkewWSM(SkewMod *m) : SimpleOSMToWSMObject(m) {}
void DeleteThis() { delete this; }
SClass_ID SuperClassID() {return WSM_OBJECT_CLASS_ID;}
Class_ID ClassID() {return SKEWWSM_CLASSID;}
TCHAR *GetObjectName() {return GetString(IDS_RB_SKEW);}
RefTargetHandle Clone(RemapDir& remap)
{return (new SkewWSM((SkewMod*)mod->Clone(remap)))->SimpleOSMToWSMClone(this,remap);}
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *SkewMod::pmapParam = NULL;
class SkewClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new SkewMod; }
const TCHAR * ClassName() { return GetString(IDS_RB_SKEW_CLASS); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(SKEWOSM_CLASS_ID,0); }
const TCHAR* Category() {return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static SkewClassDesc skewDesc;
extern ClassDesc* GetSkewModDesc() { return &skewDesc; }
class SkewWSMClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE)
{if (loading) return new SkewWSM; else return new SkewWSM(new SkewMod);}
const TCHAR * ClassName() { return GetString(IDS_RB_SKEW_CLASS); }
SClass_ID SuperClassID() { return WSM_OBJECT_CLASS_ID; }
Class_ID ClassID() { return SKEWWSM_CLASSID; }
const TCHAR* Category() {return GetSpaceWarpCatString(SPACEWARP_CAT_MODBASED);}
};
static SkewWSMClassDesc skewWSMDesc;
extern ClassDesc* GetSkewWSMDesc() { return &skewWSMDesc; }
//--- Parameter map/block descriptors -------------------------------
#define PB_AMOUNT 0
#define PB_DIR 1
#define PB_AXIS 2
#define PB_DOREGION 3
#define PB_FROM 4
#define PB_TO 5
//
//
// Parameters
static int axisIDs[] = {IDC_X,IDC_Y,IDC_Z};
static ParamUIDesc descParam[] = {
// Amount
ParamUIDesc(
PB_AMOUNT,
EDITTYPE_UNIVERSE,
IDC_SKEW_AMOUNT,IDC_SKEW_AMOUNTSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// Direction
ParamUIDesc(
PB_DIR,
EDITTYPE_FLOAT,
IDC_DIR,IDC_DIRSPINNER,
-BIGFLOAT,BIGFLOAT,
0.5f),
// Axis
ParamUIDesc(PB_AXIS,TYPE_RADIO,axisIDs,3),
// Affect region
ParamUIDesc(PB_DOREGION,TYPE_SINGLECHEKBOX,IDC_SKEW_AFFECTREGION),
// From
ParamUIDesc(
PB_FROM,
EDITTYPE_UNIVERSE,
IDC_SKEW_FROM,IDC_SKEW_FROMSPIN,
-BIGFLOAT,0.0f,
SPIN_AUTOSCALE),
// To
ParamUIDesc(
PB_TO,
EDITTYPE_UNIVERSE,
IDC_SKEW_TO,IDC_SKEW_TOSPIN,
0.0f,BIGFLOAT,
SPIN_AUTOSCALE),
};
#define PARAMDESC_LENGH 6
static ParamBlockDescID descVer0[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_INT, NULL, FALSE, 2 },
{ TYPE_INT, NULL, FALSE, 3 },
{ TYPE_FLOAT, NULL, TRUE, 4 },
{ TYPE_FLOAT, NULL, TRUE, 5 } };
#define PBLOCK_LENGTH 6
#if 0
// Array of old versions
static ParamVersionDesc versions[] = {
ParamVersionDesc(descVer0,3,0)
};
#define NUM_OLDVERSIONS 1
// Current version
#define CURRENT_VERSION 1
static ParamVersionDesc curVersion(descVer1,PBLOCK_LENGTH,CURRENT_VERSION);
#endif
#define CURRENT_VERSION 0
//--- SkewDlgProc -------------------------------
class SkewDlgProc : public ParamMapUserDlgProc {
public:
BOOL DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
void DeleteThis() {}
};
static SkewDlgProc theSkewProc;
BOOL SkewDlgProc::DlgProc(
TimeValue t,IParamMap *map,
HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg) {
case CC_SPINNER_CHANGE:
switch (LOWORD(wParam)) {
case IDC_SKEW_FROMSPIN: {
float from, to;
map->GetParamBlock()->GetValue(PB_FROM,t,from,FOREVER);
map->GetParamBlock()->GetValue(PB_TO,t,to,FOREVER);
if (from>to) {
map->GetParamBlock()->SetValue(PB_TO,t,from);
map->Invalidate();
}
break;
}
case IDC_SKEW_TOSPIN: {
float from, to;
map->GetParamBlock()->GetValue(PB_FROM,t,from,FOREVER);
map->GetParamBlock()->GetValue(PB_TO,t,to,FOREVER);
if (from>to) {
map->GetParamBlock()->SetValue(PB_FROM,t,to);
map->Invalidate();
}
break;
}
}
break;
}
return FALSE;
}
//--- Skew methods -------------------------------
SkewMod::SkewMod() : SimpleMod()
{
MakeRefByID(FOREVER, SIMPMOD_PBLOCKREF,
CreateParameterBlock(descVer0, PBLOCK_LENGTH, CURRENT_VERSION));
pblock->SetValue(PB_AXIS, TimeValue(0), 2/*Z*/);
}
IOResult SkewMod::Load(ILoad *iload)
{
Modifier::Load(iload);
//iload->RegisterPostLoadCallback(
// new ParamBlockPLCB(versions,NUM_OLDVERSIONS,&curVersion,this,SIMPMOD_PBLOCKREF));
return IO_OK;
}
void SkewMod::BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev )
{
SimpleMod::BeginEditParams(ip,flags,prev);
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_SKEWPARAM),
GetString(IDS_RB_PARAMETERS),
0);
pmapParam->SetUserDlgProc(&theSkewProc);
}
void SkewMod::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
{
SimpleMod::EndEditParams(ip,flags,next);
DestroyCPParamMap(pmapParam);
}
Interval SkewMod::GetValidity(TimeValue t)
{
float f;
Interval valid = FOREVER;
pblock->GetValue(PB_AMOUNT,t,f,valid);
pblock->GetValue(PB_DIR,t,f,valid);
pblock->GetValue(PB_FROM,t,f,valid);
pblock->GetValue(PB_TO,t,f,valid);
return valid;
}
BOOL SkewMod::GetModLimits(TimeValue t,float &zmin, float &zmax, int &axis)
{
int limit;
pblock->GetValue(PB_DOREGION,t,limit,FOREVER);
pblock->GetValue(PB_FROM,t,zmin,FOREVER);
pblock->GetValue(PB_TO,t,zmax,FOREVER);
pblock->GetValue(PB_AXIS,t,axis,FOREVER);
return limit?TRUE:FALSE;
}
RefTargetHandle SkewMod::Clone(RemapDir& remap)
{
SkewMod* newmod = new SkewMod();
newmod->ReplaceReference(SIMPMOD_PBLOCKREF,pblock->Clone(remap));
newmod->SimpleModClone(this);
return(newmod);
}
SkewDeformer::SkewDeformer()
{
tm.IdentityMatrix();
invtm.IdentityMatrix();
}
Point3 SkewDeformer::Map(int i, Point3 p)
{
float z;
p = p * tm;
z = p.z;
if (doRegion) {
if (p.z<from) {
z = from;
} else
if (p.z>to) {
z = to;
}
}
p.x += z * amountOverLength;
return p * invtm;
}
SkewDeformer::SkewDeformer(
ModContext &mc,
float amount, float dir, int naxis,
float from, float to, int doRegion,
Matrix3& modmat, Matrix3& modinv)
{
this->doRegion = doRegion;
this->from = from;
this->to = to;
Matrix3 mat;
mat.IdentityMatrix();
switch (naxis) {
case 0: mat.RotateY( -HALFPI ); break; //X
case 1: mat.RotateX( HALFPI ); break; //Y
case 2: break; //Z
}
mat.RotateZ(DegToRad(dir));
tm = modmat * mat;
invtm = Inverse(mat) * modinv;
assert (mc.box);
bbox = *mc.box;
float len = 0.0f;
if (!doRegion) {
switch (naxis) {
case 0: len = bbox.pmax.x - bbox.pmin.x; break;
case 1: len = bbox.pmax.y - bbox.pmin.y; break;
case 2: len = bbox.pmax.z - bbox.pmin.z; break;
}
} else {
len = to-from;
}
if (len==0.0f) len = 0.000001f;
amountOverLength = amount/len;
}
Deformer& SkewMod::GetDeformer(
TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
{
float amount, dir, from, to;
int axis;
int doRegion;
pblock->GetValue(PB_AMOUNT,t,amount,FOREVER);
pblock->GetValue(PB_DIR,t,dir,FOREVER);
pblock->GetValue(PB_AXIS,t,axis,FOREVER);
pblock->GetValue(PB_FROM,t,from,FOREVER);
pblock->GetValue(PB_TO,t,to,FOREVER);
pblock->GetValue(PB_DOREGION,t,doRegion,FOREVER);
static SkewDeformer deformer;
deformer = SkewDeformer(mc,amount,dir,axis,from,to,doRegion,mat,invmat);
return deformer;
}
ParamDimension *SkewMod::GetParameterDim(int pbIndex)
{
switch (pbIndex) {
case PB_AMOUNT: return stdWorldDim;
case PB_DIR: return defaultDim;
case PB_FROM: return stdWorldDim;
case PB_TO: return stdWorldDim;
default: return defaultDim;
}
}
TSTR SkewMod::GetParameterName(int pbIndex)
{
switch (pbIndex) {
case PB_AMOUNT: return GetString(IDS_RB_AMOUNT);
case PB_DIR: return GetString(IDS_RB_DIRECTION);
case PB_FROM: return GetString(IDS_RB_FROM);
case PB_TO: return GetString(IDS_RB_TO);
default: return TSTR(_T(""));
}
}
@@ -0,0 +1,737 @@
/**********************************************************************
*<
FILE: surfmod.cpp
DESCRIPTION: Varius surface modifiers
CREATED BY: Rolf Berteig
HISTORY: 11/07/95
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#include "edmdata.h"
class MatMod : public Modifier {
public:
IParamBlock *pblock;
static IParamMap *pmapParam;
MatMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) { s= GetString(IDS_RB_MATMOD); }
virtual Class_ID ClassID() { return Class_ID(MATERIALOSM_CLASS_ID,0);}
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams( IObjParam *ip,ULONG flags,Animatable *next);
TCHAR *GetObjectName() { return GetString(IDS_RB_MATERIAL3); }
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
ChannelMask ChannelsUsed() {return OBJ_CHANNELS;}
ChannelMask ChannelsChanged() {return GEOM_CHANNEL|TOPO_CHANNEL;}
Class_ID InputType() {return triObjectClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t);
IParamArray *GetParamBlock() {return pblock;}
int GetParamBlockIndex(int id) {return id;}
int NumRefs() {return 1;}
RefTargetHandle GetReference(int i) {return pblock;}
void SetReference(int i, RefTargetHandle rtarg) {pblock = (IParamBlock*)rtarg;}
int NumSubs() {return 1;}
Animatable* SubAnim(int i) {return pblock;}
TSTR SubAnimName(int i) {return GetString(IDS_RB_PARAMETERS);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *MatMod::pmapParam = NULL;
class MatClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new MatMod; }
const TCHAR * ClassName() { return GetString(IDS_RB_MATERIAL3_CLASS); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(MATERIALOSM_CLASS_ID,0); }
const TCHAR* Category() { return GetString(IDS_RB_DEFSURFACE);}
};
static MatClassDesc matDesc;
extern ClassDesc* GetMatModDesc() { return &matDesc; }
//--- Parameter map/block descriptors -------------------------------
#define PB_MATID 0
//
//
// Parameters
static ParamUIDesc descParam[] = {
// Material ID
ParamUIDesc(
PB_MATID,
EDITTYPE_INT,
IDC_MATID,IDC_MATIDSPIN,
1.0f,(float)0xffff,
0.1f),
};
#define PARAMDESC_LENGH 1
static ParamBlockDescID descVer0[] = {
{ TYPE_INT, NULL, TRUE, 0 }};
#define PBLOCK_LENGTH 1
#define CURRENT_VERSION 0
//--- MatMod methods -------------------------------
MatMod::MatMod()
{
MakeRefByID(FOREVER, 0,
CreateParameterBlock(descVer0, PBLOCK_LENGTH, CURRENT_VERSION));
pblock->SetValue(PB_MATID,0,1);
}
void MatMod::BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev)
{
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_MATERIALPARAM),
GetString(IDS_RB_PARAMETERS),
0);
}
void MatMod::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
{
DestroyCPParamMap(pmapParam);
pmapParam = NULL;
}
Interval MatMod::LocalValidity(TimeValue t)
{
int i;
Interval valid = FOREVER;
pblock->GetValue(PB_MATID,t,i,valid);
return valid;
}
RefTargetHandle MatMod::Clone(RemapDir& remap)
{
MatMod* newmod = new MatMod();
newmod->ReplaceReference(0,pblock->Clone(remap));
return newmod;
}
void MatMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
Interval valid = FOREVER;
int id;
pblock->GetValue(PB_MATID,t,id,valid);
id--;
if (id<0) id = 0;
if (id>0xffff) id = 0xffff;
assert(os->obj->IsSubClassOf(triObjectClassID));
TriObject *triOb = (TriObject *)os->obj;
BOOL useSel = triOb->mesh.selLevel==MESH_FACE;
for (int i=0; i<triOb->mesh.getNumFaces(); i++) {
if (!useSel || triOb->mesh.faceSel[i]) {
triOb->mesh.setFaceMtlIndex(i,(MtlID)id);
}
}
triOb->UpdateValidity(TOPO_CHAN_NUM,valid);
}
RefResult MatMod::NotifyRefChanged(
Interval changeInt,
RefTargetHandle hTarget,
PartID& partID,
RefMessage message)
{
switch (message) {
case REFMSG_CHANGE:
if (pmapParam && pmapParam->GetParamBlock()==pblock) {
pmapParam->Invalidate();
}
break;
case REFMSG_GET_PARAM_DIM: {
GetParamDim *gpd = (GetParamDim*)partID;
switch (gpd->index) {
case 0:
default: gpd->dim = defaultDim; break;
}
return REF_STOP;
}
case REFMSG_GET_PARAM_NAME: {
GetParamName *gpn = (GetParamName*)partID;
switch (gpn->index) {
case PB_MATID: gpn->name = GetString(IDS_RB_MATERIALID); break;
default: gpn->name = TSTR(_T("")); break;
}
return REF_STOP;
}
}
return REF_SUCCEED;
}
//-------------------------------------------------------------------
//-------------------------------------------------------------------
class SmoothMod : public Modifier {
public:
IParamBlock *pblock;
static IParamMap *pmapParam;
SmoothMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) { s= GetString(IDS_RB_SMOOTHMOD); }
virtual Class_ID ClassID() { return Class_ID(SMOOTHOSM_CLASS_ID,0);}
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams( IObjParam *ip,ULONG flags,Animatable *next);
TCHAR *GetObjectName() { return GetString(IDS_RB_SMOOTH2); }
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
ChannelMask ChannelsUsed() {return OBJ_CHANNELS;}
ChannelMask ChannelsChanged() {return GEOM_CHANNEL|TOPO_CHANNEL;}
Class_ID InputType() {return triObjectClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t);
IParamArray *GetParamBlock() {return pblock;}
int GetParamBlockIndex(int id) {return id;}
int NumRefs() {return 1;}
RefTargetHandle GetReference(int i) {return pblock;}
void SetReference(int i, RefTargetHandle rtarg) {pblock = (IParamBlock*)rtarg;}
IOResult Load(ILoad *iload);
int NumSubs() {return 1;}
Animatable* SubAnim(int i) {return pblock;}
TSTR SubAnimName(int i) {return GetString(IDS_RB_PARAMETERS);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *SmoothMod::pmapParam = NULL;
class SmoothClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) {return new SmoothMod;}
const TCHAR * ClassName() { return GetString(IDS_RB_SMOOTH2_CLASS); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(SMOOTHOSM_CLASS_ID,0); }
const TCHAR* Category() { return GetString(IDS_RB_DEFSURFACE);}
};
static SmoothClassDesc smoothDesc;
extern ClassDesc* GetSmoothModDesc() { return &smoothDesc; }
//--- Parameter map/block descriptors -------------------------------
#define PB_AUTOSMOOTH 0
#define PB_THRESHOLD 1
#define PB_SMOOTHBITS 2
#define PB_PREVENTINDIRECT 3
//
//
// Parameters
static ParamUIDesc descSmoothParam[] = {
// Auto smooth
ParamUIDesc(PB_AUTOSMOOTH,TYPE_SINGLECHEKBOX,IDC_SMOOTH_AUTO),
// Prevent Indirect Smoothing
ParamUIDesc(PB_PREVENTINDIRECT,TYPE_SINGLECHEKBOX,IDC_SMOOTH_PREVENTINDIRECT),
// Threshold
ParamUIDesc(
PB_THRESHOLD,
EDITTYPE_FLOAT,
IDC_SMOOTH_THRESH,IDC_SMOOTH_THRESHSPIN,
0.0f,180.0f,
0.1f,
stdAngleDim),
};
#define SMOOTHPARAMDESC_LENGH 3
static ParamBlockDescID descSmoothVer0[] = {
{ TYPE_INT, NULL, FALSE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_INT, NULL, FALSE, 2 }};
static ParamBlockDescID descSmoothVer1[] = {
{ TYPE_INT, NULL, FALSE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_INT, NULL, FALSE, 2 },
{ TYPE_INT, NULL, FALSE, 3 },
};
#define SMOOTHPBLOCK_LENGTH 4
// Array of old versions
static ParamVersionDesc versionsSmooth[] = {
ParamVersionDesc(descSmoothVer0,3,0)
};
#define NUM_OLDSMOOTHVERSIONS 1
#define CURRENT_SMOOTHVERSION 1
static ParamVersionDesc curSmoothVersion(descSmoothVer1,SMOOTHPBLOCK_LENGTH,CURRENT_SMOOTHVERSION);
//--- SmoothDlgProc --------------------------------
class SmoothDlgProc : public ParamMapUserDlgProc {
public:
SmoothMod *mod;
SmoothDlgProc(SmoothMod *m) {mod = m;}
BOOL DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
void DeleteThis() {delete this;}
};
static void SetSmoothButtonState(HWND hWnd,DWORD bits)
{
for (int i=IDC_SMOOTH_GRP1; i<IDC_SMOOTH_GRP1+32; i++) {
SendMessage(GetDlgItem(hWnd,i),CC_COMMAND,CC_CMD_SET_STATE,
(bits&(1<<(i-IDC_SMOOTH_GRP1)))?TRUE:FALSE);
}
}
BOOL SmoothDlgProc::DlgProc(
TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG: {
for (int i=IDC_SMOOTH_GRP1; i<IDC_SMOOTH_GRP1+32; i++) {
SendMessage(GetDlgItem(hWnd,i),CC_COMMAND,CC_CMD_SET_TYPE,CBT_CHECK);
}
IParamBlock *pblock = (IParamBlock*)map->GetParamBlock();
int bits;
pblock->GetValue(PB_SMOOTHBITS,t,bits,FOREVER);
SetSmoothButtonState(hWnd,(DWORD)bits);
break;
}
case WM_COMMAND:
if (LOWORD(wParam)>=IDC_SMOOTH_GRP1 &&
LOWORD(wParam)<=IDC_SMOOTH_GRP32) {
IParamBlock *pblock = (IParamBlock*)map->GetParamBlock();
ICustButton *iBut = GetICustButton(GetDlgItem(hWnd,LOWORD(wParam)));
int bits;
pblock->GetValue(PB_SMOOTHBITS,t,bits,FOREVER);
int shift = LOWORD(wParam) - IDC_SMOOTH_GRP1;
if (iBut->IsChecked()) {
bits |= 1<<shift;
} else {
bits &= ~(1<<shift);
}
pblock->SetValue(PB_SMOOTHBITS,t,bits);
ReleaseICustButton(iBut);
return REDRAW_VIEWS;
}
break;
default:
return TRUE;
}
return FALSE;
}
//--- SmoothMod methods -------------------------------
SmoothMod::SmoothMod()
{
MakeRefByID(FOREVER, 0,
CreateParameterBlock(descSmoothVer1, SMOOTHPBLOCK_LENGTH, CURRENT_SMOOTHVERSION));
pblock->SetValue(PB_THRESHOLD,0,DegToRad(30.0f));
}
IOResult SmoothMod::Load(ILoad *iload)
{
Modifier::Load(iload);
iload->RegisterPostLoadCallback(
new ParamBlockPLCB(versionsSmooth,NUM_OLDSMOOTHVERSIONS,&curSmoothVersion,this,0));
return IO_OK;
}
void SmoothMod::BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev)
{
pmapParam = CreateCPParamMap(
descSmoothParam,SMOOTHPARAMDESC_LENGH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_SMOOTHPARAM),
GetString(IDS_RB_PARAMETERS),
0);
pmapParam->SetUserDlgProc(new SmoothDlgProc(this));
}
void SmoothMod::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
{
DestroyCPParamMap(pmapParam);
pmapParam = NULL;
}
Interval SmoothMod::LocalValidity(TimeValue t)
{
float f;
Interval valid = FOREVER;
pblock->GetValue(PB_THRESHOLD,t,f,valid);
return valid;
}
RefTargetHandle SmoothMod::Clone(RemapDir& remap)
{
SmoothMod* newmod = new SmoothMod();
newmod->ReplaceReference(0,pblock->Clone(remap));
return newmod;
}
#if 0 // moved into mesh class
static void AutoSmooth(
Mesh *mesh,
AdjFaceList &af,
AdjEdgeList &ae,
float angle,BOOL useSel)
{
FaceClusterList clust(mesh,af,angle,useSel);
int *grp = new int[clust.count];
// For each cluster, pick the first unused bit
for (DWORD i=0; i<clust.count; i++) {
int bit = 0;
DWORD used = 0;
// Go through the faces in this cluster and see which
// bits are used
for (int j=0; j<mesh->getNumFaces(); j++) {
if (useSel&&!mesh->faceSel[j]) continue;
if (clust[j]==i) {
int c;
for (int k=0; k<3; k++) {
// New way: We gotta look at all faces that share
// a vertex even if they are not adjacent across an edge.
DWORD v = mesh->faces[j].v[k];
for (int l=0; l<ae[v].Count(); l++) {
MEdge edge = ae.edges[ae[v][l]];
if (edge.f[0]!=UNDEFINED && edge.f[0]!=(DWORD)j) {
c = clust[edge.f[0]];
if (c!=UNDEFINED && (DWORD)c<i) {
used |= 1<<(grp[c]);
}
}
if (edge.f[1]!=UNDEFINED && edge.f[1]!=(DWORD)j) {
c = clust[edge.f[1]];
if (c!=UNDEFINED && (DWORD)c<i) {
used |= 1<<(grp[c]);
}
}
}
}
}
}
// Pick the first free bit
for (j=0; j<32; j++) {
if (!((1<<j) & used)) {
bit = j;
break;
}
}
// We've got a smooth bit for this cluster!
grp[i] = bit;
}
// Now we've got bits for each cluster ID. Assign the faces.
for (int j=0; j<mesh->getNumFaces(); j++) {
if (useSel&&!mesh->faceSel[j]) continue;
assert(clust[j]!=UNDEFINED);
mesh->faces[j].smGroup = (1<<grp[clust[j]]);
}
delete[] grp;
}
#endif
void SmoothMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
Interval valid = FOREVER;
int autoSmooth, bits, prevent;
float thresh;
pblock->GetValue(PB_AUTOSMOOTH,t,autoSmooth,valid);
pblock->GetValue(PB_THRESHOLD,t,thresh,valid);
pblock->GetValue(PB_SMOOTHBITS,t,bits,valid);
pblock->GetValue(PB_PREVENTINDIRECT,t,prevent,valid);
assert(os->obj->IsSubClassOf(triObjectClassID));
TriObject *triOb = (TriObject *)os->obj;
BOOL useSel = triOb->mesh.selLevel==MESH_FACE;
if (!autoSmooth) {
for (int i=0; i<triOb->mesh.getNumFaces(); i++) {
if (!useSel || triOb->mesh.faceSel[i]) {
triOb->mesh.faces[i].smGroup = (DWORD)bits;
}
}
valid = FOREVER; // No animating without autosmooth
} else {
//AdjEdgeList ae(triOb->mesh);
//AdjFaceList af(triOb->mesh,ae);
//AutoSmooth(&triOb->mesh,af,ae,thresh,useSel);
triOb->mesh.AutoSmooth(thresh,useSel,prevent);
}
triOb->UpdateValidity(TOPO_CHAN_NUM,valid);
}
RefResult SmoothMod::NotifyRefChanged(
Interval changeInt,
RefTargetHandle hTarget,
PartID& partID,
RefMessage message)
{
switch (message) {
case REFMSG_CHANGE:
if (pmapParam && pmapParam->GetParamBlock()==pblock) {
pmapParam->Invalidate();
}
break;
case REFMSG_GET_PARAM_DIM: {
GetParamDim *gpd = (GetParamDim*)partID;
switch (gpd->index) {
case PB_THRESHOLD: gpd->dim = stdAngleDim; break;
default: gpd->dim = defaultDim; break;
}
return REF_STOP;
}
case REFMSG_GET_PARAM_NAME: {
GetParamName *gpn = (GetParamName*)partID;
switch (gpn->index) {
case PB_THRESHOLD: gpn->name = GetString(IDS_RB_THRESHOLD); break;
default: gpn->name = TSTR(_T("")); break;
}
return REF_STOP;
}
}
return REF_SUCCEED;
}
//-----------------------------------------------------------
//-----------------------------------------------------------
class NormalMod : public Modifier {
public:
IParamBlock *pblock;
static IParamMap *pmapParam;
NormalMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) { s= GetString(IDS_RB_NORMALMOD); }
virtual Class_ID ClassID() { return Class_ID(NORMALOSM_CLASS_ID,0);}
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams( IObjParam *ip,ULONG flags,Animatable *next);
TCHAR *GetObjectName() { return GetString(IDS_RB_NORMAL); }
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
ChannelMask ChannelsUsed() {return OBJ_CHANNELS;}
ChannelMask ChannelsChanged() {return TOPO_CHANNEL;}
Class_ID InputType() {return triObjectClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t);
IParamArray *GetParamBlock() {return pblock;}
int GetParamBlockIndex(int id) {return id;}
int NumRefs() {return 1;}
RefTargetHandle GetReference(int i) {return pblock;}
void SetReference(int i, RefTargetHandle rtarg) {pblock = (IParamBlock*)rtarg;}
int NumSubs() {return 1;}
Animatable* SubAnim(int i) {return pblock;}
TSTR SubAnimName(int i) {return GetString(IDS_RB_PARAMETERS);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *NormalMod::pmapParam = NULL;
class NormalClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new NormalMod;}
const TCHAR * ClassName() { return GetString(IDS_RB_NORMAL_CLASS); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(NORMALOSM_CLASS_ID,0);}
const TCHAR* Category() { return GetString(IDS_RB_DEFSURFACE);}
};
static NormalClassDesc normalDesc;
extern ClassDesc* GetNormalModDesc() { return &normalDesc; }
//--- Parameter map/block descriptors -------------------------------
#define PB_UNIFY 0
#define PB_FLIP 1
//
//
// Parameters
static ParamUIDesc descNormParam[] = {
// Unify
ParamUIDesc(PB_UNIFY,TYPE_SINGLECHEKBOX,IDC_NORM_UNIFY),
// Flip
ParamUIDesc(PB_FLIP,TYPE_SINGLECHEKBOX,IDC_NORM_FLIP),
};
#define NORMPARAMDESC_LENGH 2
static ParamBlockDescID descNormVer0[] = {
{ TYPE_INT, NULL, FALSE, 0 },
{ TYPE_INT, NULL, FALSE, 1 }};
#define NORMPBLOCK_LENGTH 2
#define CURRENT_NORMVERSION 0
//--- NormalMod methods -------------------------------
NormalMod::NormalMod()
{
MakeRefByID(FOREVER, 0,
CreateParameterBlock(descNormVer0, NORMPBLOCK_LENGTH, CURRENT_NORMVERSION));
}
void NormalMod::BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev)
{
pmapParam = CreateCPParamMap(
descNormParam,NORMPARAMDESC_LENGH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_NORMALPARAM),
GetString(IDS_RB_PARAMETERS),
0);
}
void NormalMod::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
{
DestroyCPParamMap(pmapParam);
pmapParam = NULL;
}
Interval NormalMod::LocalValidity(TimeValue t)
{
return FOREVER;
}
RefTargetHandle NormalMod::Clone(RemapDir& remap)
{
NormalMod* newmod = new NormalMod();
newmod->ReplaceReference(0,pblock->Clone(remap));
return newmod;
}
void NormalMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
Interval valid = FOREVER;
int flip, unify;
pblock->GetValue(PB_FLIP,t,flip,valid);
pblock->GetValue(PB_UNIFY,t,unify,valid);
assert(os->obj->IsSubClassOf(triObjectClassID));
TriObject *triOb = (TriObject *)os->obj;
BOOL useSel = triOb->mesh.selLevel==MESH_FACE;
if (unify) {
triOb->mesh.UnifyNormals(useSel);
}
if (flip) {
for (int i=0; i<triOb->mesh.getNumFaces(); i++) {
if (!useSel || triOb->mesh.faceSel[i]) {
FlipMeshNormal(&triOb->mesh,(DWORD)i);
}
}
}
triOb->UpdateValidity(TOPO_CHAN_NUM,valid);
}
RefResult NormalMod::NotifyRefChanged(
Interval changeInt,
RefTargetHandle hTarget,
PartID& partID,
RefMessage message)
{
switch (message) {
case REFMSG_CHANGE:
if (pmapParam && pmapParam->GetParamBlock()==pblock) {
pmapParam->Invalidate();
}
break;
}
return REF_SUCCEED;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,484 @@
/**********************************************************************
*<
FILE: taper.cpp
DESCRIPTION: Taper OSM
CREATED BY: Dan Silva & Rolf Berteig
HISTORY: created 30 Jauary, 1995
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#include "simpmod.h"
#include "simpobj.h"
// in mods.cpp
extern HINSTANCE hInstance;
#define BIGFLOAT float(999999)
class TaperMod : public SimpleMod {
public:
static IParamMap *pmapParam;
TaperMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) { s= GetString(IDS_RB_TAPERMOD); }
virtual Class_ID ClassID() { return Class_ID(TAPEROSM_CLASS_ID,0);}
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev );
void EndEditParams( IObjParam *ip,ULONG flags,Animatable *next );
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() { return GetString(IDS_RB_TAPER); }
IOResult Load(ILoad *iload);
// From simple mod
Deformer& GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat);
Interval GetValidity(TimeValue t);
ParamDimension *GetParameterDim(int pbIndex);
TSTR GetParameterName(int pbIndex);
BOOL GetModLimits(TimeValue t,float &zmin, float &zmax, int &axis);
void InvalidateUI() {if (pmapParam) pmapParam->Invalidate();}
};
class TaperDeformer: public Deformer {
public:
Matrix3 tm,invtm;
Box3 bbox;
TimeValue time;
float k1,k2, from, to;
int doRegion, naxis;
BOOL doX, doY, sym;
TaperDeformer();
TaperDeformer(
TimeValue t, ModContext &mc,
float amt, float crv, int naxis,
int eaxis, int sym,
float from, float to, int doRegion,
Matrix3& modmat, Matrix3& modinv);
void SetAxis(Matrix3 &tmAxis);
void SetK(float K1, float K2) { k1 = K1; k2 = K2; }
Point3 Map(int i, Point3 p);
};
#define TAPERWSM_CLASSID Class_ID(TAPEROSM_CLASS_ID,1)
class TaperWSM : public SimpleOSMToWSMObject {
public:
TaperWSM() {}
TaperWSM(TaperMod *m) : SimpleOSMToWSMObject(m) {}
void DeleteThis() { delete this; }
SClass_ID SuperClassID() {return WSM_OBJECT_CLASS_ID;}
Class_ID ClassID() {return TAPERWSM_CLASSID;}
TCHAR *GetObjectName() {return GetString(IDS_RB_TAPER);}
RefTargetHandle Clone(RemapDir& remap)
{return (new TaperWSM((TaperMod*)mod->Clone(remap)))->SimpleOSMToWSMClone(this,remap);}
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *TaperMod::pmapParam;
class TaperClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new TaperMod; }
const TCHAR * ClassName() { return GetString(IDS_RB_TAPER_CLASS); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(TAPEROSM_CLASS_ID,0); }
const TCHAR* Category() {return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static TaperClassDesc taperDesc;
extern ClassDesc* GetTaperModDesc() { return &taperDesc; }
class TaperWSMClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE)
{if (loading) return new TaperWSM; else return new TaperWSM(new TaperMod);}
const TCHAR * ClassName() { return GetString(IDS_RB_TAPER_CLASS); }
SClass_ID SuperClassID() { return WSM_OBJECT_CLASS_ID; }
Class_ID ClassID() { return TAPERWSM_CLASSID; }
const TCHAR* Category() {return GetSpaceWarpCatString(SPACEWARP_CAT_MODBASED);}
};
static TaperWSMClassDesc taperWSMDesc;
extern ClassDesc* GetTaperWSMDesc() { return &taperWSMDesc; }
//--- Parameter map/block descriptors -------------------------------
#define PB_AMT 0
#define PB_CRV 1
#define PB_AXIS 2
#define PB_EFFECTAXIS 3
#define PB_SYMMETRY 4
#define PB_DOREGION 5
#define PB_FROM 6
#define PB_TO 7
//
//
// Parameters
static int axisIDs[] = {IDC_X,IDC_Y,IDC_Z};
static int effectAxisIDs[] = {IDC_EFFECT_X,IDC_EFFECT_Y,IDC_EFFECT_BOTH};
static ParamUIDesc descParam[] = {
// Amount
ParamUIDesc(
PB_AMT,
EDITTYPE_FLOAT,
IDC_AMT,IDC_AMTSPINNER,
-10.0f,10.0f,
0.01f),
// Curve
ParamUIDesc(
PB_CRV,
EDITTYPE_FLOAT,
IDC_CRV,IDC_CRVSPINNER,
-10.0f,10.0f,
0.01f),
// Primary Axis
ParamUIDesc(PB_AXIS,TYPE_RADIO,axisIDs,3),
// Effect Axis
ParamUIDesc(PB_EFFECTAXIS,TYPE_RADIO,effectAxisIDs,3),
// Symmetry
ParamUIDesc(PB_SYMMETRY,TYPE_SINGLECHEKBOX,IDC_TAPER_SYMMETRY),
// Affect region
ParamUIDesc(PB_DOREGION,TYPE_SINGLECHEKBOX,IDC_TAPER_AFFECTREGION),
// From
ParamUIDesc(
PB_FROM,
EDITTYPE_UNIVERSE,
IDC_TAPER_FROM,IDC_TAPER_FROMSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// To
ParamUIDesc(
PB_TO,
EDITTYPE_UNIVERSE,
IDC_TAPER_TO,IDC_TAPER_TOSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
};
#define PARAMDESC_LENGH 8
static ParamBlockDescID descVer0[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_INT, NULL, FALSE, 2 } };
static ParamBlockDescID descVer1[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 1 },
{ TYPE_INT, NULL, FALSE, 2 },
{ TYPE_INT, NULL, FALSE, 3 },
{ TYPE_INT, NULL, TRUE, 4 },
{ TYPE_INT, NULL, FALSE, 5 },
{ TYPE_FLOAT, NULL, TRUE, 6 },
{ TYPE_FLOAT, NULL, TRUE, 7 } };
#define PBLOCK_LENGTH 8
// Array of old versions
static ParamVersionDesc versions[] = {
ParamVersionDesc(descVer0,3,0)
};
#define NUM_OLDVERSIONS 1
// Current version
#define CURRENT_VERSION 1
static ParamVersionDesc curVersion(descVer1,PBLOCK_LENGTH,CURRENT_VERSION);
//--- TaperDlgProc -------------------------------
class TaperDlgProc : public ParamMapUserDlgProc {
public:
BOOL DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
void InitEffectAxis(HWND hWnd,TimeValue t,IParamMap *map);
void DeleteThis() {}
};
static TaperDlgProc theTaperProc;
void TaperDlgProc::InitEffectAxis(HWND hWnd,TimeValue t,IParamMap *map)
{
int axis;
map->GetParamBlock()->GetValue(PB_AXIS,t,axis,FOREVER);
switch (axis) {
case 0:
SetWindowText(GetDlgItem(hWnd,IDC_EFFECT_X),_T("Z"));
SetWindowText(GetDlgItem(hWnd,IDC_EFFECT_Y),_T("Y"));
SetWindowText(GetDlgItem(hWnd,IDC_EFFECT_BOTH),_T("ZY"));
break;
case 1:
SetWindowText(GetDlgItem(hWnd,IDC_EFFECT_X),_T("X"));
SetWindowText(GetDlgItem(hWnd,IDC_EFFECT_Y),_T("Z"));
SetWindowText(GetDlgItem(hWnd,IDC_EFFECT_BOTH),_T("XZ"));
break;
case 2:
SetWindowText(GetDlgItem(hWnd,IDC_EFFECT_X),_T("X"));
SetWindowText(GetDlgItem(hWnd,IDC_EFFECT_Y),_T("Y"));
SetWindowText(GetDlgItem(hWnd,IDC_EFFECT_BOTH),_T("XY"));
break;
}
}
BOOL TaperDlgProc::DlgProc(
TimeValue t,IParamMap *map,
HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
InitEffectAxis(hWnd,t,map);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_X:
case IDC_Y:
case IDC_Z:
InitEffectAxis(hWnd,t,map);
break;
}
break;
case CC_SPINNER_CHANGE:
switch (LOWORD(wParam)) {
case IDC_TAPER_FROMSPIN: {
float from, to;
map->GetParamBlock()->GetValue(PB_FROM,t,from,FOREVER);
map->GetParamBlock()->GetValue(PB_TO,t,to,FOREVER);
if (from>to) {
map->GetParamBlock()->SetValue(PB_TO,t,from);
map->Invalidate();
}
break;
}
case IDC_TAPER_TOSPIN: {
float from, to;
map->GetParamBlock()->GetValue(PB_FROM,t,from,FOREVER);
map->GetParamBlock()->GetValue(PB_TO,t,to,FOREVER);
if (from>to) {
map->GetParamBlock()->SetValue(PB_FROM,t,to);
map->Invalidate();
}
break;
}
}
break;
}
return FALSE;
}
//--- Bend methods -------------------------------
TaperMod::TaperMod()
{
MakeRefByID(FOREVER, SIMPMOD_PBLOCKREF,
CreateParameterBlock(descVer1, PBLOCK_LENGTH, CURRENT_VERSION));
pblock->SetValue(PB_AXIS, TimeValue(0), 2/*Z*/);
pblock->SetValue(PB_EFFECTAXIS, TimeValue(0), 2/*XY*/);
}
IOResult TaperMod::Load(ILoad *iload)
{
Modifier::Load(iload);
iload->RegisterPostLoadCallback(
new ParamBlockPLCB(versions,NUM_OLDVERSIONS,&curVersion,this,SIMPMOD_PBLOCKREF));
return IO_OK;
}
void TaperMod::BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev)
{
SimpleMod::BeginEditParams(ip,flags,prev);
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_TAPERPARAM),
GetString(IDS_RB_PARAMETERS),
0);
pmapParam->SetUserDlgProc(&theTaperProc);
}
void TaperMod::EndEditParams(IObjParam *ip, ULONG flags,Animatable *next)
{
SimpleMod::EndEditParams(ip,flags,next);
DestroyCPParamMap(pmapParam);
}
Interval TaperMod::GetValidity(TimeValue t)
{
float f;
int i;
Interval valid = FOREVER;
pblock->GetValue(PB_AMT,t,f,valid);
pblock->GetValue(PB_CRV,t,f,valid);
pblock->GetValue(PB_FROM,t,f,valid);
pblock->GetValue(PB_TO,t,f,valid);
pblock->GetValue(PB_SYMMETRY,t,i,valid);
return valid;
}
BOOL TaperMod::GetModLimits(TimeValue t,float &zmin, float &zmax, int &axis)
{
int limit;
pblock->GetValue(PB_DOREGION,t,limit,FOREVER);
pblock->GetValue(PB_FROM,t,zmin,FOREVER);
pblock->GetValue(PB_TO,t,zmax,FOREVER);
pblock->GetValue(PB_AXIS,t,axis,FOREVER);
return limit?TRUE:FALSE;
}
RefTargetHandle TaperMod::Clone(RemapDir& remap)
{
TaperMod* newmod = new TaperMod();
newmod->ReplaceReference(SIMPMOD_PBLOCKREF,pblock->Clone(remap));
newmod->SimpleModClone(this);
return(newmod);
}
TaperDeformer::TaperDeformer()
{
tm.IdentityMatrix();
time = 0;
}
void TaperDeformer::SetAxis(Matrix3 &tmAxis)
{
Matrix3 itm = Inverse(tmAxis);
tm = tm*tmAxis;
invtm = itm*invtm;
}
Point3 TaperDeformer::Map(int i, Point3 p)
{
float f, z, l;
l = (bbox.pmax[naxis]-bbox.pmin[naxis]);
if ( l == float(0) ) return p;
p = p * tm;
if (doRegion) {
if (p.z<from) {
z = from/l;
} else
if (p.z>to) {
z = to/l;
} else {
z = p.z/l;
}
} else {
z = p.z/l;
}
if (sym && z<0.0f) z = -z;
f = float(1.0) + z*k1 + k2*z*(float(1.0)-z);
if (doX) p.x *= f;
if (doY) p.y *= f;
p = p * invtm;
return p;
}
TaperDeformer::TaperDeformer(
TimeValue t, ModContext &mc,
float amt, float crv, int naxis,
int eaxis, int sym,
float from, float to, int doRegion,
Matrix3& modmat, Matrix3& modinv)
{
this->naxis = naxis;
this->doRegion = doRegion;
this->from = from;
this->to = to;
this->sym = sym;
switch (eaxis) {
case 0: doX = TRUE; doY = FALSE; break;
case 1: doX = FALSE; doY = TRUE; break;
case 2: doX = TRUE; doY = TRUE; break;
}
Interval valid;
Matrix3 mat;
time = t;
tm = modmat;
invtm = modinv;
mat.IdentityMatrix();
SetK(amt,crv);
switch (naxis) {
case 0: mat.RotateY( -HALFPI ); break; //x
case 1: mat.RotateX( HALFPI ); break; //y
case 2: break; //z
}
SetAxis( mat );
bbox = *mc.box;
}
Deformer& TaperMod::GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
{
static TaperDeformer deformer;
float amt, crv, from, to;
int doRegion, axis;
int eaxis, sym;
pblock->GetValue(PB_AMT,t,amt,FOREVER);
pblock->GetValue(PB_CRV,t,crv,FOREVER);
pblock->GetValue(PB_AXIS,t,axis,FOREVER);
pblock->GetValue(PB_EFFECTAXIS,t,eaxis,FOREVER);
pblock->GetValue(PB_SYMMETRY,t,sym,FOREVER);
pblock->GetValue(PB_FROM,t,from,FOREVER);
pblock->GetValue(PB_TO,t,to,FOREVER);
pblock->GetValue(PB_DOREGION,t,doRegion,FOREVER);
deformer = TaperDeformer(t,mc,amt,crv,axis,eaxis,sym,from,to,doRegion,mat,invmat);
return deformer;
}
ParamDimension *TaperMod::GetParameterDim(int pbIndex)
{
switch (pbIndex) {
case PB_AMT: return stdNormalizedDim;
case PB_CRV: return stdNormalizedDim;
case PB_FROM: return stdWorldDim;
case PB_TO: return stdWorldDim;
case PB_SYMMETRY: return defaultDim;
default: return defaultDim;
}
}
TSTR TaperMod::GetParameterName(int pbIndex)
{
switch (pbIndex) {
case PB_AMT: return GetString(IDS_RB_AMOUNT);
case PB_CRV: return GetString(IDS_RB_CURVITURE);
case PB_FROM: return GetString(IDS_RB_FROM);
case PB_TO: return GetString(IDS_RB_TO);
case PB_SYMMETRY: return GetString(IDS_RB_SYMMETRY);
default: return TSTR(_T(""));
}
}
@@ -0,0 +1,411 @@
/**********************************************************************
*<
FILE: tessmod.cpp
DESCRIPTION: A tessellation modifier
CREATED BY: Rolf Berteig
(Modified later, MNMesh stuff added, by Steve Anderson)
HISTORY: 10/22/96
(Modified 3/21/97)
*> Copyright (c) 1994, 1996, 1997, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "MNMath.h"
#include "iparamm.h"
#define DEF_FACE_TYPE 0 // triangle
#define DEF_TESS_TYPE 0 // edge
#define DEF_TENSION 25.0f
#define DEF_ITERS 0 // Really, 1.
class TessMod : public Modifier {
public:
IParamBlock *pblock;
static int LastFaceType, LastType;
static IObjParam *ip;
static IParamMap *pmapParam;
static TessMod *editMod;
TessMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) {s = GetString(IDS_RB_TESSMOD);}
virtual Class_ID ClassID() { return Class_ID(TESSELLATE_CLASS_ID,0);}
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip,ULONG flags,Animatable *next);
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_TESSMOD);}
IOResult Load (ILoad *iload);
// From modifier
ChannelMask ChannelsUsed() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_SUBSEL_TYPE|PART_TEXMAP|PART_VERTCOLOR;}
ChannelMask ChannelsChanged() {return PART_GEOM|PART_TOPO|PART_SELECT|PART_TEXMAP|PART_VERTCOLOR;}
Class_ID InputType() {return triObjectClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t);
// From BaseObject
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
IParamArray *GetParamBlock() {return pblock;}
int GetParamBlockIndex(int id) {return id;}
int NumRefs() {return 1;}
RefTargetHandle GetReference(int i) {return pblock;}
void SetReference(int i, RefTargetHandle rtarg) {pblock=(IParamBlock*)rtarg;}
int NumSubs() {return 1;}
Animatable* SubAnim(int i) {return GetReference(i);}
TSTR SubAnimName(int i) {return _T("");}
RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message);
};
//--- ClassDescriptor and class vars ---------------------------------
IObjParam *TessMod::ip = NULL;
IParamMap *TessMod::pmapParam = NULL;
TessMod *TessMod::editMod = NULL;
int TessMod::LastFaceType = DEF_FACE_TYPE;
int TessMod::LastType = DEF_TESS_TYPE;
static HIMAGELIST hFaceImages = NULL;
static void LoadImages() {
if (hFaceImages) return;
HBITMAP hBitmap, hMask;
hFaceImages = ImageList_Create(17, 15, ILC_MASK, 3, 0); // "17" is kluge to get square centered -SA 9706
hBitmap = LoadBitmap (hInstance,MAKEINTRESOURCE(IDB_FACESELTYPES));
hMask = LoadBitmap (hInstance,MAKEINTRESOURCE(IDB_MASK_FACESELTYPES));
ImageList_Add(hFaceImages, hBitmap, hMask);
DeleteObject(hBitmap);
DeleteObject(hMask);
}
class TessClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new TessMod; }
const TCHAR * ClassName() { return GetString(IDS_RB_TESSMOD); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(TESSELLATE_CLASS_ID,0); }
const TCHAR* Category() { return GetString(IDS_RB_DEFDEFORMATIONS);}
void ResetClassParams (BOOL fileReset);
};
void TessClassDesc::ResetClassParams (BOOL fileReset) {
TessMod::LastType = DEF_TESS_TYPE;
TessMod::LastFaceType = DEF_FACE_TYPE;
}
static TessClassDesc tessDesc;
ClassDesc* GetTessModDesc() {return &tessDesc;}
//--- Parameter map/block descriptors -------------------------------
#define PB_TYPE 0
#define PB_TENSION 1
#define PB_ITERATIONS 2
#define PB_FACE_TYPE 3
//
//
// Parameters
static int typeIDs[] = {IDC_TES_EDGE,IDC_TES_CENTER};
static int iterationsIDs[] = {IDC_ITERATIONS1,IDC_ITERATIONS2,IDC_ITERATIONS3,IDC_ITERATIONS4};
static ParamUIDesc descParam[] = {
// Type
ParamUIDesc(PB_TYPE,TYPE_RADIO,typeIDs,2),
// Falloff
ParamUIDesc(
PB_TENSION,
EDITTYPE_FLOAT,
IDC_TENSION,IDC_TENSIONSPIN,
-100.0f,100.0f,
0.1f),
// Iterations
ParamUIDesc(PB_ITERATIONS,TYPE_RADIO,iterationsIDs,4),
};
#define PARAMDESC_LENGTH 3
static ParamBlockDescID descVer0[] = {
{ TYPE_INT, NULL, FALSE, 0 }, // Type
{ TYPE_FLOAT, NULL, TRUE, 1 }, // Tension
{ TYPE_INT, NULL, FALSE, 2 }, // Iterations
};
static ParamBlockDescID descVer1[] = {
{ TYPE_INT, NULL, FALSE, 0 }, // Type
{ TYPE_FLOAT, NULL, TRUE, 1 }, // Tension
{ TYPE_INT, NULL, FALSE, 2 }, // Iterations
{ TYPE_INT, NULL, FALSE, 3 } // Face type
};
#define PBLOCK_LENGTH 4
// Array of old versions
static ParamVersionDesc versions[] = {
ParamVersionDesc(descVer0,3,0),
};
#define NUM_OLDVERSIONS 1
#define CURRENT_VERSION 1
static ParamVersionDesc curVersion (descVer1, PBLOCK_LENGTH, CURRENT_VERSION);
// Undo/redo for tri/poly buttons:
class TriPolyRestore : public RestoreObj {
public:
int was_poly;
TessMod * tm;
TriPolyRestore (TessMod *mod);
void Restore (int isUndo);
void Redo () { Restore (FALSE); }
int Size () { return (sizeof(TessMod *) + sizeof (int)); }
TSTR Description() { return TSTR(_T("TessMod Tri/Poly toggle")); }
};
TriPolyRestore::TriPolyRestore (TessMod *mod) {
tm = mod;
assert (tm);
assert (tm->pblock);
tm->pblock->GetValue (PB_FACE_TYPE, TimeValue(0), was_poly, FOREVER);
}
void TriPolyRestore::Restore (int isUndo) {
if (!tm) return;
if (!tm->pmapParam) return;
ICustButton *iTri, *iPoly;
iTri = GetICustButton (GetDlgItem (tm->pmapParam->GetHWnd(), IDC_TES_FACE_TRI));
iPoly = GetICustButton (GetDlgItem (tm->pmapParam->GetHWnd(), IDC_TES_FACE_POLY));
iTri->SetCheck (!was_poly);
iPoly->SetCheck (was_poly);
ReleaseICustButton (iTri);
ReleaseICustButton (iPoly);
was_poly = !was_poly;
}
// Face-type dlg user proc
class TessModDlgProc : public ParamMapUserDlgProc {
public:
TessMod *mod;
TessModDlgProc () { mod = NULL; }
BOOL DlgProc (TimeValue t, IParamMap *map, HWND hWnd,
UINT msg, WPARAM wParam, LPARAM lParam);
void DeleteThis () { }
};
BOOL TessModDlgProc::DlgProc (TimeValue t, IParamMap *map, HWND hWnd,
UINT msg,WPARAM wParam,LPARAM lParam) {
if (mod==NULL) return FALSE;
if (msg != WM_COMMAND) return FALSE;
ICustButton *iTri, *iPoly;
switch (LOWORD (wParam)) {
case IDC_TES_FACE_TRI:
theHold.Begin ();
theHold.Put (new TriPolyRestore (mod));
iTri = GetICustButton (GetDlgItem (hWnd, IDC_TES_FACE_TRI));
iPoly = GetICustButton (GetDlgItem (hWnd, IDC_TES_FACE_POLY));
mod->pblock->SetValue (PB_FACE_TYPE, t, 0);
iTri->SetCheck (1);
iPoly->SetCheck (0);
ReleaseICustButton (iTri);
ReleaseICustButton (iPoly);
theHold.Accept (GetString (IDS_SA_TRI_POLY_RESTORE));
break;
case IDC_TES_FACE_POLY:
theHold.Begin ();
theHold.Put (new TriPolyRestore (mod));
iTri = GetICustButton (GetDlgItem (hWnd, IDC_TES_FACE_TRI));
iPoly = GetICustButton (GetDlgItem (hWnd, IDC_TES_FACE_POLY));
mod->pblock->SetValue (PB_FACE_TYPE, t, 1);
iTri->SetCheck (0);
iPoly->SetCheck (1);
ReleaseICustButton (iTri);
ReleaseICustButton (iPoly);
theHold.Accept (GetString (IDS_SA_TRI_POLY_RESTORE));
break;
}
return FALSE;
}
static TessModDlgProc theTessModDlgProc;
//--- tessellate mod methods -------------------------------
TessMod::TessMod()
{
pblock = NULL;
MakeRefByID (FOREVER, 0,
CreateParameterBlock(descVer1, PBLOCK_LENGTH, CURRENT_VERSION));
pblock->SetValue (PB_TENSION, 0, DEF_TENSION);
pblock->SetValue (PB_TYPE, 0, LastType);
pblock->SetValue (PB_ITERATIONS, 0, DEF_ITERS); // "1" iteration
pblock->SetValue (PB_FACE_TYPE, 0, LastFaceType);
LoadImages();
}
void TessMod::BeginEditParams (IObjParam *ip, ULONG flags,Animatable *prev) {
this->ip = ip;
editMod = this;
TimeValue t = ip->GetTime();
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_BEGIN_EDIT);
SetAFlag(A_MOD_BEING_EDITED);
pmapParam = CreateCPParamMap (descParam,PARAMDESC_LENGTH,
pblock, ip, hInstance, MAKEINTRESOURCE(IDD_TESSPARAM),
GetString(IDS_RB_PARAMETERS), 0);
theTessModDlgProc.mod = this;
pmapParam->SetUserDlgProc (&theTessModDlgProc);
int ft;
pblock->GetValue (PB_FACE_TYPE, TimeValue(0), ft, FOREVER);
HWND hParam = pmapParam->GetHWnd();
ICustButton *iFaceTri = GetICustButton (GetDlgItem (hParam, IDC_TES_FACE_TRI));
iFaceTri->SetImage(hFaceImages, 0, 0, 0, 0, 16, 15);
iFaceTri->SetType (CBT_CHECK);
iFaceTri->SetCheck (!ft);
iFaceTri->SetTooltip (TRUE, GetString (IDS_SA_TRIANGLE));
ReleaseICustButton (iFaceTri);
ICustButton *iFacePoly = GetICustButton (GetDlgItem (hParam, IDC_TES_FACE_POLY));
iFacePoly->SetImage(hFaceImages, 1, 1, 1, 1, 16, 15);
iFacePoly->SetType (CBT_CHECK);
iFacePoly->SetCheck (ft);
iFacePoly->SetTooltip (TRUE, GetString (IDS_SA_POLYGON));
ReleaseICustButton (iFacePoly);
}
void TessMod::EndEditParams (IObjParam *ip,ULONG flags,Animatable *next) {
this->ip = NULL;
editMod = NULL;
TimeValue t = ip->GetTime();
// NOTE: This flag must be cleared before sending the REFMSG_END_EDIT
ClearAFlag(A_MOD_BEING_EDITED);
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_END_EDIT);
DestroyCPParamMap(pmapParam);
theTessModDlgProc.mod = NULL;
pblock->GetValue (PB_FACE_TYPE, t, LastFaceType, FOREVER);
pblock->GetValue (PB_TYPE, t, LastType, FOREVER);
}
RefTargetHandle TessMod::Clone(RemapDir& remap) {
TessMod *mod = new TessMod();
mod->ReplaceReference(0,pblock->Clone(remap));
return mod;
}
IOResult TessMod::Load (ILoad *iload) {
Modifier::Load(iload);
// Add following when there's a new pblock version.
iload->RegisterPostLoadCallback(
new ParamBlockPLCB(versions,NUM_OLDVERSIONS,&curVersion,this,0));
return IO_OK;
}
void TessMod::ModifyObject (TimeValue t, ModContext &mc, ObjectState *os, INode *node) {
if (!os->obj->IsSubClassOf (triObjectClassID)) return;
int type, iterations, faceType;
float tens;
BOOL ignoreSel = FALSE;
Interval iv = os->obj->ChannelValidity (t, GEOM_CHAN_NUM);
iv &= os->obj->ChannelValidity (t, TOPO_CHAN_NUM);
iv &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM);
iv &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM);
iv &= os->obj->ChannelValidity (t, TEXMAP_CHAN_NUM);
iv &= os->obj->ChannelValidity (t, VERT_COLOR_CHAN_NUM);
pblock->GetValue(PB_TYPE,t,type,iv);
pblock->GetValue(PB_ITERATIONS,t,iterations,iv);
iterations++;
pblock->GetValue (PB_FACE_TYPE, t, faceType, iv);
TriObject *tobj = (TriObject*)os->obj;
if (faceType == 0) {
if (tobj->mesh.selLevel != MESH_FACE) ignoreSel = TRUE;
if (type) {
for (int i=0; i<iterations; i++) tobj->mesh.FaceCenterTessellate(ignoreSel);
} else {
pblock->GetValue(PB_TENSION,t,tens,iv);
for (int i=0; i<iterations; i++) tobj->mesh.EdgeTessellate(tens/400.0f,ignoreSel);
}
} else {
Mesh & msh = tobj->Mesh();
MNMesh mm(msh);
mm.MakePolyMesh ();
mm.MakeConvex ();
mm.TargetFacesBySelection (msh.selLevel);
if (type) {
for (int i=0; i<iterations; i++) mm.TessellateByCenters ();
} else {
pblock->GetValue(PB_TENSION,t,tens,iv);
tens /= 400.0f;
for (int i=0; i<iterations; i++) mm.TessellateByEdges (tens);
}
mm.OutToTri (msh);
}
os->obj->UpdateValidity (GEOM_CHAN_NUM, iv);
os->obj->UpdateValidity (TOPO_CHAN_NUM, iv);
os->obj->UpdateValidity (SELECT_CHAN_NUM, iv);
os->obj->UpdateValidity (SUBSEL_TYPE_CHAN_NUM, iv);
os->obj->UpdateValidity (TEXMAP_CHAN_NUM, iv);
os->obj->UpdateValidity (VERT_COLOR_CHAN_NUM, iv);
}
Interval TessMod::LocalValidity(TimeValue t) {
Interval iv = FOREVER;
int type, iterations, faceType;
float tens;
pblock->GetValue(PB_TYPE,t,type,iv);
pblock->GetValue(PB_ITERATIONS,t,iterations,iv);
pblock->GetValue (PB_FACE_TYPE, t, faceType, iv);
if (!type) pblock->GetValue(PB_TENSION,t,tens,iv);
return iv;
}
RefResult TessMod::NotifyRefChanged (Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message) {
int type;
switch (message) {
case REFMSG_CHANGE:
if (editMod==this && pmapParam) {
pblock->GetValue (PB_TYPE, TimeValue(0), type, FOREVER);
ISpinnerControl *spin;
spin = GetISpinner (GetDlgItem (pmapParam->GetHWnd(), IDC_TENSIONSPIN));
spin->Enable (!type);
ReleaseISpinner (spin);
pmapParam->Invalidate();
}
break;
case REFMSG_GET_PARAM_DIM: {
GetParamDim *gpd = (GetParamDim*)partID;
switch (gpd->index) {
case PB_TENSION: gpd->dim = stdPercentDim; break;
}
return REF_STOP;
}
case REFMSG_GET_PARAM_NAME: {
GetParamName *gpn = (GetParamName*)partID;
switch (gpn->index) {
case PB_TENSION: gpn->name = GetString(IDS_TESS_TENSION); break;
}
return REF_STOP;
}
}
return REF_SUCCEED;
}
@@ -0,0 +1,679 @@
/**********************************************************************
*<
FILE: twist.cpp
DESCRIPTION: Twist OSM
CREATED BY: Dan Silva & Rolf Berteig
MODIFIED BY: Keith Trummel
HISTORY: created 30 Jauary, 1995
Keith modified bend.cpp to create this on 13 March, 1995
updated for new API on 24 April, 1995
updated and added authorization code 11 May, 1995
*> Copyright (c) 1995, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
#include "simpmod.h"
#include "simpobj.h"
#include <stdio.h>
#ifdef CHECK_AUTHORIZE
#define TwistMod TwistMod2
#define TwistDeformer TwistDeformer2
#define AuthInfo AuthInfo2
#define TwistClassDesc TwistClassDesc2
#endif
//------------------------------------------------------
// Functions used by the rest of the library
//------------------------------------------------------
static int authorized = 0;
static int
IsAuthorized()
{
return authorized;
}
static void
Authorize()
{
authorized = 1;
}
static void
UnAuthorize()
{
authorized = 0;
}
//////////////////////////////////////////////////////////
// in mods.cpp
extern HINSTANCE hInstance;
#define ABS(x) (((x) >= 0) ? (x) : -(x))
#define BIGFLOAT float(999999)
class TwistMod : public SimpleMod {
static HWND hAuthWnd;
static int inAuthorizationMode;
static IParamMap *pmapParam;
public:
TwistMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) { s= GetString(IDS_RB_TWISTMOD); }
#ifdef CHECK_AUTHORIZE
virtual Class_ID ClassID() { return Class_ID(TWISTOSM_CLASS_ID,1);}
#else
virtual Class_ID ClassID() { return Class_ID(TWISTOSM_CLASS_ID,0);}
#endif
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev );
void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next );
RefTargetHandle Clone(RemapDir& remap = NoRemap());
#ifdef CHECK_AUTHORIZE
TCHAR *GetObjectName() { return GetString(IDS_RB_TWIST2); }
#else
TCHAR *GetObjectName() { return GetString(IDS_RB_TWIST); }
#endif
IOResult Load(ILoad *iload);
// From simple mod
Deformer& GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat);
Interval GetValidity(TimeValue t);
ParamDimension *GetParameterDim(int pbIndex);
TSTR GetParameterName(int pbIndex);
BOOL GetModLimits(TimeValue t,float &zmin, float &zmax, int &axis);
void InvalidateUI() {if (pmapParam) pmapParam->Invalidate();}
};
class TwistDeformer: public Deformer {
public:
Matrix3 tm,invtm;
Box3 bbox;
TimeValue time;
float theAngle;
float height;
float angleOverHeight, from, to, bias;
int doRegion, doBias;
TwistDeformer();
TwistDeformer(
TimeValue t, ModContext &mc,
float angle, int naxis, float bias,
float from, float to, int doRegion,
Matrix3& modmat, Matrix3& modinv);
void SetAxis(Matrix3 &tmAxis);
void CalcHeight(int axis, float angle);
Point3 Map(int i, Point3 p);
};
#define TWISTWSM_CLASSID Class_ID(TWISTOSM_CLASS_ID,2)
class TwistWSM : public SimpleOSMToWSMObject {
public:
TwistWSM() {}
TwistWSM(TwistMod *m) : SimpleOSMToWSMObject(m) {}
void DeleteThis() { delete this; }
SClass_ID SuperClassID() {return WSM_OBJECT_CLASS_ID;}
Class_ID ClassID() {return TWISTWSM_CLASSID;}
TCHAR *GetObjectName() {return GetString(IDS_RB_TWIST);}
RefTargetHandle Clone(RemapDir& remap)
{return (new TwistWSM((TwistMod*)mod->Clone(remap)))->SimpleOSMToWSMClone(this,remap);}
};
//--- ClassDescriptor and class vars ---------------------------------
HWND TwistMod::hAuthWnd = NULL;
int TwistMod::inAuthorizationMode = 0;
IParamMap *TwistMod::pmapParam = NULL;
static BOOL CALLBACK AuthorizationDialogProc( HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam );
static BOOL CALLBACK AuthRollupProc( HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam );
class AuthInfo {
public:
TwistMod *twistMod;
IObjParam *iobjParam;
int create;
};
class TwistClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new TwistMod; }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
#ifdef CHECK_AUTHORIZE
const TCHAR * ClassName() { return GetString(IDS_RB_TWIST2_CLASS); }
Class_ID ClassID() { return Class_ID(TWISTOSM_CLASS_ID,1); }
#else
const TCHAR * ClassName() { return GetString(IDS_RB_TWIST_CLASS); }
Class_ID ClassID() { return Class_ID(TWISTOSM_CLASS_ID,0); }
#endif
const TCHAR* Category() {return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static TwistClassDesc twistDesc;
#ifndef CHECK_AUTHORIZE
extern ClassDesc* GetTwistModDesc() { return &twistDesc; }
#else
extern ClassDesc* GetTwistModDesc2() { return &twistDesc; }
#endif
class TwistWSMClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE)
{if (loading) return new TwistWSM; else return new TwistWSM(new TwistMod);}
const TCHAR * ClassName() { return GetString(IDS_RB_TWIST_CLASS); }
SClass_ID SuperClassID() { return WSM_OBJECT_CLASS_ID; }
Class_ID ClassID() { return TWISTWSM_CLASSID; }
const TCHAR* Category() {return GetSpaceWarpCatString(SPACEWARP_CAT_MODBASED);}
};
static TwistWSMClassDesc twistWSMDesc;
extern ClassDesc* GetTwistWSMDesc() { return &twistWSMDesc; }
//--- Parameter map/block descriptors -------------------------------
#define PB_ANGLE 0
#define PB_BIAS 1
#define PB_AXIS 2
#define PB_DOREGION 3
#define PB_FROM 4
#define PB_TO 5
//
//
// Parameters
static int axisIDs[] = {IDC_X,IDC_Y,IDC_Z};
static ParamUIDesc descParam[] = {
// Angle
ParamUIDesc(
PB_ANGLE,
EDITTYPE_FLOAT,
IDC_ANGLE,IDC_ANGLESPINNER,
-BIGFLOAT,BIGFLOAT,
0.5f),
// Bias
ParamUIDesc(
PB_BIAS,
EDITTYPE_FLOAT,
IDC_TWIST_BIAS,IDC_TWIST_BIASSPIN,
-100.0f,100.0f,
0.5f),
// Axis
ParamUIDesc(PB_AXIS,TYPE_RADIO,axisIDs,3),
// Affect region
ParamUIDesc(PB_DOREGION,TYPE_SINGLECHEKBOX,IDC_TWIST_AFFECTREGION),
// From
ParamUIDesc(
PB_FROM,
EDITTYPE_UNIVERSE,
IDC_TWIST_FROM,IDC_TWIST_FROMSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// To
ParamUIDesc(
PB_TO,
EDITTYPE_UNIVERSE,
IDC_TWIST_TO,IDC_TWIST_TOSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
};
#define PARAMDESC_LENGH 6
static ParamBlockDescID descVer0[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 },
{ TYPE_INT, NULL, FALSE, 1 } };
static ParamBlockDescID descVer1[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 },
{ TYPE_FLOAT, NULL, TRUE, 5 },
{ TYPE_INT, NULL, FALSE, 1 },
{ TYPE_INT, NULL, FALSE, 2 },
{ TYPE_FLOAT, NULL, TRUE, 3 },
{ TYPE_FLOAT, NULL, TRUE, 4 } };
#define PBLOCK_LENGTH 6
// Array of old versions
static ParamVersionDesc versions[] = {
ParamVersionDesc(descVer0,2,0)
};
#define NUM_OLDVERSIONS 1
// Current version
#define CURRENT_VERSION 1
static ParamVersionDesc curVersion(descVer1,PBLOCK_LENGTH,CURRENT_VERSION);
//--- TwistDlgProc -------------------------------
class TwistDlgProc : public ParamMapUserDlgProc {
public:
BOOL DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
void DeleteThis() {}
};
static TwistDlgProc theTwistProc;
#ifndef CHECK_AUTHORIZE
BOOL TwistDlgProc::DlgProc(
TimeValue t,IParamMap *map,
HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg) {
case CC_SPINNER_CHANGE:
switch (LOWORD(wParam)) {
case IDC_TWIST_FROMSPIN: {
float from, to;
map->GetParamBlock()->GetValue(PB_FROM,t,from,FOREVER);
map->GetParamBlock()->GetValue(PB_TO,t,to,FOREVER);
if (from>to) {
map->GetParamBlock()->SetValue(PB_TO,t,from);
map->Invalidate();
}
break;
}
case IDC_TWIST_TOSPIN: {
float from, to;
map->GetParamBlock()->GetValue(PB_FROM,t,from,FOREVER);
map->GetParamBlock()->GetValue(PB_TO,t,to,FOREVER);
if (from>to) {
map->GetParamBlock()->SetValue(PB_FROM,t,to);
map->Invalidate();
}
break;
}
}
break;
}
return FALSE;
}
#endif
//--- Twist methods -------------------------------
TwistMod::TwistMod() : SimpleMod()
{
MakeRefByID(FOREVER, SIMPMOD_PBLOCKREF,
CreateParameterBlock(descVer1, PBLOCK_LENGTH, CURRENT_VERSION));
pblock->SetValue( PB_AXIS, TimeValue(0), 2/*Z*/ );
}
IOResult TwistMod::Load(ILoad *iload)
{
Modifier::Load(iload);
iload->RegisterPostLoadCallback(
new ParamBlockPLCB(versions,NUM_OLDVERSIONS,&curVersion,this,SIMPMOD_PBLOCKREF));
return IO_OK;
}
void TwistMod::BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev )
{
static AuthInfo authInfo;
#ifdef CHECK_AUTHORIZE
if (!IsAuthorized()) {
authInfo.twistMod = this;
authInfo.iobjParam = ip;
authInfo.create = flags&BEGIN_EDIT_CREATE;
hAuthWnd = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_AUTHMSG),
AuthRollupProc,
GetString(IDS_RB_TWISTPLUGIN),
(LPARAM)&authInfo );
inAuthorizationMode = 1;
return;
}
#endif
inAuthorizationMode = 0;
SimpleMod::BeginEditParams(ip,flags,prev);
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_TWISTPARAM),
GetString(IDS_RB_PARAMETERS),
0);
pmapParam->SetUserDlgProc(&theTwistProc);
}
void TwistMod::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
{
if (inAuthorizationMode) {
if (flags&END_EDIT_REMOVEUI) {
if (hAuthWnd) {
ip->DeleteRollupPage(hAuthWnd);
hAuthWnd = NULL;
}
}
return;
}
SimpleMod::EndEditParams(ip,flags,next);
DestroyCPParamMap(pmapParam);
}
Interval TwistMod::GetValidity(TimeValue t)
{
float f;
Interval valid = FOREVER;
pblock->GetValue(PB_ANGLE,t,f,valid);
pblock->GetValue(PB_BIAS,t,f,valid);
pblock->GetValue(PB_FROM,t,f,valid);
pblock->GetValue(PB_TO,t,f,valid);
return valid;
}
BOOL TwistMod::GetModLimits(TimeValue t,float &zmin, float &zmax, int &axis)
{
int limit;
pblock->GetValue(PB_DOREGION,t,limit,FOREVER);
pblock->GetValue(PB_FROM,t,zmin,FOREVER);
pblock->GetValue(PB_TO,t,zmax,FOREVER);
pblock->GetValue(PB_AXIS,t,axis,FOREVER);
return limit?TRUE:FALSE;
}
RefTargetHandle TwistMod::Clone(RemapDir& remap)
{
TwistMod* newmod = new TwistMod();
newmod->ReplaceReference(SIMPMOD_PBLOCKREF,pblock->Clone());
newmod->SimpleModClone(this);
return(newmod);
}
TwistDeformer::TwistDeformer()
{
tm.IdentityMatrix();
time = 0;
}
TwistDeformer::TwistDeformer(
TimeValue t, ModContext &mc,
float angle, int naxis, float bias,
float from, float to, int doRegion,
Matrix3& modmat, Matrix3& modinv)
{
this->doRegion = doRegion;
this->from = from;
this->to = to;
if (bias!=0.0f) {
this->bias = 1.0f-(bias+100.0f)/200.0f;
if (this->bias < 0.00001f) this->bias = 0.00001f;
if (this->bias > 0.99999f) this->bias = 0.99999f;
this->bias = float(log(this->bias)/log(0.5));
doBias = TRUE;
} else {
this->bias = 1.0f;
doBias = FALSE;
}
Matrix3 mat;
Interval valid;
time = t;
tm = modmat;
invtm = modinv;
mat.IdentityMatrix();
switch ( naxis ) {
case 0: mat.RotateY( -HALFPI ); break; //X
case 1: mat.RotateX( HALFPI ); break; //Y
case 2: break; //Z
}
SetAxis( mat );
assert (mc.box);
bbox = *mc.box;
CalcHeight(naxis,DegToRad(angle));
}
void TwistDeformer::SetAxis(Matrix3 &tmAxis)
{
Matrix3 itm = Inverse(tmAxis);
tm = tm*tmAxis;
invtm = itm*invtm;
}
void TwistDeformer::CalcHeight(int axis, float angle)
{
switch ( axis ) {
case 0:
height = bbox.pmax.x - bbox.pmin.x;
break;
case 1:
height = bbox.pmax.y - bbox.pmin.y;
break;
case 2:
height = bbox.pmax.z - bbox.pmin.z;
break;
}
if (height==0.0f) {
theAngle = 0.0f;
angleOverHeight = 0.0f;
} else {
theAngle = angle;
angleOverHeight = angle / height;
}
}
Point3 TwistDeformer::Map(int i, Point3 p)
{
float x, y, z, cosine, sine, a;
if (theAngle==0.0f) return p;
p = p * tm;
x = p.x;
y = p.y;
if (doRegion) {
if (p.z<from) {
z = from;
} else
if (p.z>to) {
z = to;
} else {
z = p.z;
}
} else {
z = p.z;
}
if (doBias) {
float u = z/height;
a = theAngle * (float)pow(fabs(u), bias);
if (u<0.0) a = -a;
} else {
a = z * angleOverHeight;
}
cosine = float(cos(a));
sine = float(sin(a));
p.x = cosine*x + sine*y;
p.y = -sine*x + cosine*y;
p = p * invtm;
return p;
}
Deformer& TwistMod::GetDeformer(
TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
{
float angle, from, to, bias;
int axis;
int doRegion;
static TwistDeformer deformer;
pblock->GetValue(PB_ANGLE,t,angle,FOREVER);
pblock->GetValue(PB_AXIS,t,axis,FOREVER);
pblock->GetValue(PB_FROM,t,from,FOREVER);
pblock->GetValue(PB_TO,t,to,FOREVER);
pblock->GetValue(PB_BIAS,t,bias,FOREVER);
pblock->GetValue(PB_DOREGION,t,doRegion,FOREVER);
deformer = TwistDeformer(t,mc,angle,axis,bias,from,to,doRegion,mat,invmat);
return deformer;
}
ParamDimension *TwistMod::GetParameterDim(int pbIndex)
{
switch (pbIndex) {
case PB_ANGLE: return defaultDim;
case PB_FROM: return stdWorldDim;
case PB_TO: return stdWorldDim;
case PB_BIAS: return defaultDim;
default: return defaultDim;
}
}
TSTR TwistMod::GetParameterName(int pbIndex)
{
switch (pbIndex) {
case PB_ANGLE: return GetString(IDS_RB_ANGLE);
case PB_FROM: return GetString(IDS_RB_FROM);
case PB_TO: return GetString(IDS_RB_TO);
case PB_BIAS: return GetString(IDS_RB_BIAS);
default: return TSTR(_T(""));
}
}
//--- Authorization Code -------------------------------------------
static void OutputLockID (HWND hWnd, unsigned int lockID)
{
char string[10];
PAINTSTRUCT ps;
HDC hDC;
InvalidateRect (hWnd, NULL, TRUE);
hDC = BeginPaint (hWnd, &ps);
SetBkMode (hDC, TRANSPARENT);
sprintf (string, "%0x", lockID);
TextOut (hDC, 0, 0, string, strlen(string));
EndPaint (hWnd, &ps);
}
static BOOL CALLBACK AuthRollupProc( HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam )
{
AuthInfo *authInfo = (AuthInfo *) GetWindowLong (hDlg, GWL_USERDATA);
switch (message) {
case WM_CREATE:
break;
case WM_INITDIALOG:
authInfo = (AuthInfo *) lParam;
SetWindowLong (hDlg, GWL_USERDATA, (LONG) authInfo);
return TRUE;
case WM_COMMAND:
switch (wParam) {
case IDC_AUTHORIZE:
DialogBox (hInstance, MAKEINTRESOURCE(IDD_AUTHORIZE),
hDlg, AuthorizationDialogProc);
if (IsAuthorized()) {
authInfo->twistMod->EndEditParams (authInfo->iobjParam, BEGIN_EDIT_CREATE,NULL);
authInfo->twistMod->BeginEditParams (authInfo->iobjParam,
authInfo->create?BEGIN_EDIT_CREATE:0,NULL);
}
return TRUE;
case IDCANCEL:
EndDialog (hDlg, 0);
return TRUE;
}
}
return FALSE;
}
static BOOL CALLBACK AuthorizationDialogProc( HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam )
{
#define AUTH_LENGTH 20
static HWND hCtrlWin;
static char authString[AUTH_LENGTH];
static unsigned int lockID;
unsigned int authNum;
switch (message) {
case WM_INITDIALOG:
hCtrlWin = GetDlgItem (hDlg, IDC_LOCKID);
SetDlgItemText (hDlg, IDC_EDIT2, authString);
SetFocus (GetDlgItem (hDlg, IDC_EDIT2));
lockID = HardwareLockID ();
return FALSE;
case WM_COMMAND:
switch (wParam) {
case IDC_AUTHORIZE:
GetDlgItemText (hDlg, IDC_EDIT2, authString, AUTH_LENGTH);
sscanf (authString, "%x", &authNum);
if (authNum != lockID) {
// char buffer[50];
// sprintf (buffer, "Incorrect authorization string %s %0x",
// authString, authNum);
TSTR buf1 = GetString(IDS_RB_INCORRECTSTRING);
TSTR buf2 = GetString(IDS_RB_AUTHORIZATION);
MessageBox (NULL, buf1, buf2,MB_ICONINFORMATION);
}
else
Authorize();
EndDialog (hDlg, 0);
return TRUE;
case IDCANCEL:
EndDialog (hDlg, 0);
return TRUE;
}
case WM_PAINT:
OutputLockID (hCtrlWin, lockID);
break;
}
return FALSE;
}
@@ -0,0 +1,5 @@
#include "mods.h"
#include "twist.cpp"
@@ -0,0 +1,5 @@
#include "mods.h"
//#define CHECK_AUTHORIZE
//#include "twist.cpp"
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,359 @@
/**********************************************************************
*<
FILE: uvwxform.cpp
DESCRIPTION: Transforms UVW coords
CREATED BY: Rolf Berteig
HISTORY: 10/26/96
*> Copyright (c) 1994, All Rights Reserved.
**********************************************************************/
#include "mods.h"
#include "iparamm.h"
class UVWXFormMod : public Modifier {
public:
IParamBlock *pblock;
static IObjParam *ip;
static IParamMap *pmapParam;
static UVWXFormMod *editMod;
UVWXFormMod();
// From Animatable
void DeleteThis() { delete this; }
void GetClassName(TSTR& s) {s = GetString(IDS_RB_UVWXFORMMOD);}
virtual Class_ID ClassID() { return Class_ID(UVW_XFORM_CLASS_ID,0);}
RefTargetHandle Clone(RemapDir& remap = NoRemap());
TCHAR *GetObjectName() {return GetString(IDS_RB_UVWXFORMMOD);}
void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
void EndEditParams(IObjParam *ip,ULONG flags,Animatable *next);
IOResult Load(ILoad *iload);
// From modifier
ChannelMask ChannelsUsed() {return PART_TEXMAP|PART_VERTCOLOR;}
ChannelMask ChannelsChanged() {return PART_TEXMAP|PART_VERTCOLOR;}
Class_ID InputType() {return triObjectClassID;}
void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
Interval LocalValidity(TimeValue t);
// From BaseObject
CreateMouseCallBack* GetCreateMouseCallBack() {return NULL;}
IParamArray *GetParamBlock() {return pblock;}
int GetParamBlockIndex(int id) {return id;}
int NumRefs() {return 1;}
RefTargetHandle GetReference(int i) {return pblock;}
void SetReference(int i, RefTargetHandle rtarg) {pblock = (IParamBlock*)rtarg;}
int NumSubs() {return 1;}
Animatable* SubAnim(int i) {return pblock;}
TSTR SubAnimName(int i) {return _T("");}
RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message);
};
//--- ClassDescriptor and class vars ---------------------------------
IParamMap *UVWXFormMod::pmapParam = NULL;
IObjParam *UVWXFormMod::ip = NULL;
UVWXFormMod *UVWXFormMod::editMod = NULL;
class UVWXFormClassDesc:public ClassDesc {
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new UVWXFormMod; }
const TCHAR * ClassName() { return GetString(IDS_RB_UVWXFORMMOD); }
SClass_ID SuperClassID() { return OSM_CLASS_ID; }
Class_ID ClassID() { return Class_ID(UVW_XFORM_CLASS_ID,0); }
const TCHAR* Category() { return GetString(IDS_RB_DEFDEFORMATIONS);}
};
static UVWXFormClassDesc uvwxformDesc;
ClassDesc* GetUVWXFormModDesc() {return &uvwxformDesc;}
//--- Parameter map/block descriptors -------------------------------
#define PB_UTILE 0
#define PB_VTILE 1
#define PB_WTILE 2
#define PB_UOFFSET 3
#define PB_VOFFSET 4
#define PB_WOFFSET 5
#define PB_UFLIP 6
#define PB_VFLIP 7
#define PB_WFLIP 8
#define PB_CHANNEL 9
//
//
// Parameters
static int chanIDs[] = {IDC_MAP_CHAN1,IDC_MAP_CHAN2};
static ParamUIDesc descParam[] = {
// U Tile
ParamUIDesc(
PB_UTILE,
EDITTYPE_FLOAT,
IDC_MAP_UTILE,IDC_MAP_UTILESPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// V Tile
ParamUIDesc(
PB_VTILE,
EDITTYPE_FLOAT,
IDC_MAP_VTILE,IDC_MAP_VTILESPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// W Tile
ParamUIDesc(
PB_WTILE,
EDITTYPE_FLOAT,
IDC_MAP_WTILE,IDC_MAP_WTILESPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// U Offset
ParamUIDesc(
PB_UOFFSET,
EDITTYPE_FLOAT,
IDC_MAP_UOFFSET,IDC_MAP_UOFFSETSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// V Offset
ParamUIDesc(
PB_VOFFSET,
EDITTYPE_FLOAT,
IDC_MAP_VOFFSET,IDC_MAP_VOFFSETSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// W Offset
ParamUIDesc(
PB_WOFFSET,
EDITTYPE_FLOAT,
IDC_MAP_WOFFSET,IDC_MAP_WOFFSETSPIN,
-BIGFLOAT,BIGFLOAT,
SPIN_AUTOSCALE),
// U Flip
ParamUIDesc(PB_UFLIP,TYPE_SINGLECHEKBOX,IDC_MAP_UFLIP),
// V Flip
ParamUIDesc(PB_VFLIP,TYPE_SINGLECHEKBOX,IDC_MAP_VFLIP),
// W Flip
ParamUIDesc(PB_WFLIP,TYPE_SINGLECHEKBOX,IDC_MAP_WFLIP),
// Channel
ParamUIDesc(PB_CHANNEL,TYPE_RADIO,chanIDs,2),
};
#define PARAMDESC_LENGTH 10
static ParamBlockDescID descVer0[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 }, // U Tile
{ TYPE_FLOAT, NULL, TRUE, 1 }, // V Tile
{ TYPE_FLOAT, NULL, TRUE, 2 }, // W Tile
{ TYPE_FLOAT, NULL, TRUE, 3 }, // U Offset
{ TYPE_FLOAT, NULL, TRUE, 4 }, // V Offset
{ TYPE_FLOAT, NULL, TRUE, 5 }, // W Offset
{ TYPE_INT, NULL, FALSE, 6 }, // U Flip
{ TYPE_INT, NULL, FALSE, 7 }, // V Flip
{ TYPE_INT, NULL, FALSE, 8 }, // W Flip
};
static ParamBlockDescID descVer1[] = {
{ TYPE_FLOAT, NULL, TRUE, 0 }, // U Tile
{ TYPE_FLOAT, NULL, TRUE, 1 }, // V Tile
{ TYPE_FLOAT, NULL, TRUE, 2 }, // W Tile
{ TYPE_FLOAT, NULL, TRUE, 3 }, // U Offset
{ TYPE_FLOAT, NULL, TRUE, 4 }, // V Offset
{ TYPE_FLOAT, NULL, TRUE, 5 }, // W Offset
{ TYPE_INT, NULL, FALSE, 6 }, // U Flip
{ TYPE_INT, NULL, FALSE, 7 }, // V Flip
{ TYPE_INT, NULL, FALSE, 8 }, // W Flip
{ TYPE_INT, NULL, FALSE, 9 }, // channel
};
#define PBLOCK_LENGTH 10
// Array of old versions
static ParamVersionDesc versions[] = {
ParamVersionDesc(descVer0,9,0),
};
#define NUM_OLDVERSIONS 1
// Current version
#define CURRENT_VERSION 1
static ParamVersionDesc curVersion(descVer1,PBLOCK_LENGTH,CURRENT_VERSION);
//--- UVWXForm mod methods -------------------------------
UVWXFormMod::UVWXFormMod()
{
MakeRefByID(
FOREVER, 0,
CreateParameterBlock(
descVer1, PBLOCK_LENGTH, CURRENT_VERSION));
pblock->SetValue(PB_UTILE,0,1.0f);
pblock->SetValue(PB_VTILE,0,1.0f);
pblock->SetValue(PB_WTILE,0,1.0f);
}
IOResult UVWXFormMod::Load(ILoad *iload)
{
Modifier::Load(iload);
iload->RegisterPostLoadCallback(
new ParamBlockPLCB(versions,NUM_OLDVERSIONS,&curVersion,this,0));
return IO_OK;
}
void UVWXFormMod::BeginEditParams(
IObjParam *ip, ULONG flags,Animatable *prev)
{
this->ip = ip;
editMod = this;
TimeValue t = ip->GetTime();
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_BEGIN_EDIT);
SetAFlag(A_MOD_BEING_EDITED);
pmapParam = CreateCPParamMap(
descParam,PARAMDESC_LENGTH,
pblock,
ip,
hInstance,
MAKEINTRESOURCE(IDD_UVWXFORMPARAM),
GetString(IDS_RB_PARAMETERS),
0);
}
void UVWXFormMod::EndEditParams(
IObjParam *ip,ULONG flags,Animatable *next)
{
this->ip = NULL;
editMod = NULL;
TimeValue t = ip->GetTime();
// NOTE: This flag must be cleared before sending the REFMSG_END_EDIT
ClearAFlag(A_MOD_BEING_EDITED);
NotifyDependents(Interval(t,t), PART_ALL, REFMSG_END_EDIT);
DestroyCPParamMap(pmapParam);
}
RefTargetHandle UVWXFormMod::Clone(RemapDir& remap)
{
UVWXFormMod *mod = new UVWXFormMod();
mod->ReplaceReference(0,pblock->Clone(remap));
return mod;
}
void UVWXFormMod::ModifyObject(
TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
if (os->obj->IsSubClassOf(triObjectClassID)) {
TriObject *tobj = (TriObject*)os->obj;
Mesh &mesh = tobj->mesh;
Interval iv = FOREVER;
float ut, vt, wt, uo, vo, wo;
int uf, vf, wf, channel;
pblock->GetValue(PB_UTILE,t,ut,iv);
pblock->GetValue(PB_VTILE,t,vt,iv);
pblock->GetValue(PB_WTILE,t,wt,iv);
pblock->GetValue(PB_UOFFSET,t,uo,iv);
pblock->GetValue(PB_VOFFSET,t,vo,iv);
pblock->GetValue(PB_WOFFSET,t,wo,iv);
pblock->GetValue(PB_UFLIP,t,uf,iv);
pblock->GetValue(PB_VFLIP,t,vf,iv);
pblock->GetValue(PB_WFLIP,t,wf,iv);
pblock->GetValue(PB_CHANNEL,t,channel,iv);
int ct = channel ? mesh.numCVerts : mesh.numTVerts;
for (int i=0; i<ct; i++) {
Point3 uvw = channel ? mesh.vertCol[i] : mesh.tVerts[i];
if (uf) uvw.x = 1.0f-uvw.x;
if (vf) uvw.y = 1.0f-uvw.y;
if (wf) uvw.z = 1.0f-uvw.z;
if (ut!=0.0f) uvw.x *= ut;
if (vt!=0.0f) uvw.y *= vt;
if (wt!=0.0f) uvw.z *= wt;
uvw.x += uo;
uvw.y += vo;
uvw.z += wo;
if (channel)
mesh.vertCol[i] = uvw;
else mesh.tVerts[i] = uvw;
}
os->obj->UpdateValidity(TEXMAP_CHAN_NUM,iv);
}
}
Interval UVWXFormMod::LocalValidity(TimeValue t)
{
Interval iv = FOREVER;
float f;
pblock->GetValue(PB_UTILE,t,f,iv);
pblock->GetValue(PB_VTILE,t,f,iv);
pblock->GetValue(PB_WTILE,t,f,iv);
pblock->GetValue(PB_UOFFSET,t,f,iv);
pblock->GetValue(PB_VOFFSET,t,f,iv);
pblock->GetValue(PB_WOFFSET,t,f,iv);
return iv;
}
RefResult UVWXFormMod::NotifyRefChanged(
Interval changeInt,RefTargetHandle hTarget,
PartID& partID, RefMessage message)
{
switch (message) {
case REFMSG_CHANGE:
if (editMod==this && pmapParam) pmapParam->Invalidate();
break;
case REFMSG_GET_PARAM_DIM: {
GetParamDim *gpd = (GetParamDim*)partID;
switch (gpd->index) {
case PB_UTILE:
case PB_VTILE:
case PB_WTILE:
case PB_UOFFSET:
case PB_VOFFSET:
case PB_WOFFSET: gpd->dim = stdNormalizedDim; break;
}
return REF_STOP;
}
case REFMSG_GET_PARAM_NAME: {
GetParamName *gpn = (GetParamName*)partID;
switch (gpn->index) {
case PB_UTILE: gpn->name = GetString(IDS_RB_UTILE); break;
case PB_VTILE: gpn->name = GetString(IDS_RB_VTILE); break;
case PB_WTILE: gpn->name = GetString(IDS_RB_WTILE); break;
case PB_UOFFSET: gpn->name = GetString(IDS_RB_UOFFSET); break;
case PB_VOFFSET: gpn->name = GetString(IDS_RB_VOFFSET); break;
case PB_WOFFSET: gpn->name = GetString(IDS_RB_WOFFSET); break;
}
return REF_STOP;
}
}
return REF_SUCCEED;
}
File diff suppressed because it is too large Load Diff