51static GenSubObjType _SubObjectTypeVertex(1);
57static BOOL CALLBACK _sot_dialog_proc(HWND hWnd,
UINT message,WPARAM wParam,LPARAM lParam);
58static BOOL CALLBACK _skeleton_dialog_thunk(HWND hWnd,
UINT message,WPARAM wParam,LPARAM lParam);
59static BOOL CALLBACK _bone_influence_dialog_thunk(HWND hWnd,
UINT message,WPARAM wParam,LPARAM lParam);
60static TriObject * Get_Tri_Object(TimeValue t,ObjectState & os,Interval & valid,
BOOL & needsdel);
61static float Bone_Distance(INode * bone,TimeValue time,
const Point3 & vertex);
89 const TCHAR*
Category() {
return _T(
"Westwood Space Warps"); }
110 const TCHAR *
Category() {
return _T(
"Westwood Space Warps"); }
130 if (
msg == MOUSE_POINT) {
131 Point3 pos = vpt->GetPointOnCP(m);
132 mat.IdentityMatrix();
179 SimpleWSMObject::BeginEditParams(ip,flags,prev);
198 SetWindowLong(
SotHWND,GWL_USERDATA,(LPARAM)ip);
221 SimpleWSMObject::EndEditParams(ip,flags,next);
223 if (flags & END_EDIT_REMOVEUI) {
264 if (i < SimpleWSMObject::NumRefs()) {
265 return SimpleWSMObject::GetReference(i);
277 if (i < SimpleWSMObject::NumRefs()) {
278 SimpleWSMObject::SetReference(i,rtarg);
281 assert(boneidx >= 0);
282 assert(boneidx <
BoneTab.Count());
283 BoneTab[boneidx] = (INode *)rtarg;
292 case REFMSG_TARGET_DELETED:
293 for (i=0; i<
BoneTab.Count(); i++) {
317 return &_SkinCreateCB;
360 mesh.InvalidateGeomCache();
367 f->setVerts(a, b, c);
369 f->setEdgeVisFlags(1,1,1);
450 MakeRefByID(
FOREVER,refidx,node);
461 MakeRefByID(
FOREVER,refidx,node);
470 for (
int i=0; i<nodetab.Count(); i++) {
489 for (
int i=0; i<nodetab.Count(); i++) {
506 for (
int i=0; i<
BoneTab.Count(); i++) {
515 for (
int i=0; i<
BoneTab.Count(); i++) {
516 if (
BoneTab[i] == node)
return i;
524 SimpleWSMObject::Save(isave);
532 isave->Write(&numbones,
sizeof(
ULONG),&nb);
540 SimpleWSMObject::Load(iload);
546 while (IO_OK==(res=iload->OpenChunk())) {
548 switch (iload->CurChunkID()) {
552 res = iload->Read(&numbones,
sizeof(numbones),&nb);
554 for (
int i=0; i<
BoneTab.Count(); i++) {
573 float mindist = 10000.0f;
577 for (
int boneidx = 0; boneidx <
BoneTab.Count(); boneidx++) {
581 float bonedist = Bone_Distance(
BoneTab[boneidx],basetime,vertex);
582 if (bonedist < mindist) {
661 const TCHAR * ptype[] = {
"Vertices" };
698 if (flags & END_EDIT_REMOVEUI) {
699 Remove_Bone_Influence_Dialog();
727 return Interval(t,t+1);
735 default:
return NULL;
751 case REFMSG_TARGET_DELETED:
771 assert(os->obj->IsSubClassOf(triObjectClassID));
772 TriObject *triobj = (TriObject *)os->obj;
783 if (skindata ==
NULL) {
797 triobj->mesh.vertSel = skindata->
VertSel;
798 triobj->mesh.SetDispFlag(DISP_VERTTICKS|DISP_SELVERTS);
800 if (triobj->mesh.selLevel != MESH_VERTEX) {
801 triobj->mesh.selLevel = MESH_VERTEX;
804 triobj->mesh.selLevel = MESH_OBJECT;
805 triobj->mesh.ClearDispFlag(DISP_VERTTICKS|DISP_SELVERTS);
811 for (
int vidx = 0; vidx < triobj->NumPoints(); vidx++) {
825 if ((boneidx != -1) && (boneidx < WSMObjectRef->Num_Bones())) {
845 pnew = triobj->GetPoint(vidx);
855 TimeValue basetime =
WSMObjectRef->Get_Base_Pose_Time();
856 Matrix3 basetm = bone->GetObjectTM(basetime);
857 Matrix3 curtm = bone->GetObjectTM(t);
858 pnew = (pnew *
Inverse(basetm)) * curtm;
862 triobj->SetPoint(vidx,pnew);
870 triobj->PointsWereChanged();
881 Modifier::Save(isave);
888 isave->Write(&sl,
sizeof(
short),&nb);
896 Modifier::Load(iload);
902 while (IO_OK==(res=iload->OpenChunk())) {
904 switch (iload->CurChunkID()) {
908 res = iload->Read(&sl,
sizeof(
short),&nb);
927 return skindata->
Save(isave);
943 return newskin->
Load(iload);
960 Remove_Bone_Influence_Dialog();
965 Install_Bone_Influence_Dialog();
978 NotifyDependents(
FOREVER, PART_SUBSEL_TYPE|PART_DISPLAY, REFMSG_CHANGE);
989 NotifyDependents(
FOREVER, SELECT_CHANNEL|DISP_ATTRIB_CHANNEL|SUBSEL_TYPE_CHANNEL, REFMSG_CHANGE);
1011 MakeHitRegion(hr,type, crossing,4,p);
1012 mat = inode->GetObjectTM(t);
1017 GraphicsWindow *gw = vpt->getGW();
1018 gw->setHitRegion(&hr);
1019 gw->setTransform(mat);
1020 gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM);
1023 gw->setRndLimits(gw->getRndLimits() | GW_BACKCULL);
1025 gw->setRndLimits(gw->getRndLimits() & ~GW_BACKCULL);
1033 SubObjHitList hitlist;
1034 MeshSubHitRec * rec;
1036 ObjectState os = inode->EvalWorldState(
InterfacePtr->GetTime());
1037 TriObject * tobj = Get_Tri_Object(
InterfacePtr->GetTime(),os,valid,needsdel);
1038 res = tobj->mesh.SubObjectHitTest(gw,gw->getMaterial(),&hr,flags | SUBHIT_VERTS,hitlist);
1043 rec = hitlist.First();
1051 vpt->LogHit(inode,mc,rec->dist,rec->index,
NULL);
1058 gw->setRndLimits(savedLimits);
1084 if (theHold.Holding() && !SelData->held) {
1085 theHold.Put(
new SubSelRestore(
this,SelData));
1087 theHold.Accept(_T(
"Select Vertex"));
1090 BitArray * array = &(skindata->
VertSel);
1098 if ((*array)[hitRec->hitInfo]) {
1099 array->Clear(hitRec->hitInfo);
1101 array->Set(hitRec->hitInfo,selected);
1104 array->Set(hitRec->hitInfo,selected);
1108 hitRec = hitRec->Next();
1113 NotifyDependents(
FOREVER, PART_SELECT, REFMSG_CHANGE);
1120 ModContextList mcList;
1128 for (
int i = 0; i < mcList.Count(); i++) {
1132 if (skindata==
NULL)
continue;
1134 ObjectState os = nodes[i]->EvalWorldState(
InterfacePtr->GetTime());
1135 TriObject * tobj = Get_Tri_Object(
InterfacePtr->GetTime(),os,valid,needsdel);
1146 if (theHold.Holding()) {
1147 theHold.Put(
new VertexSelRestore(meshData,
this));
1150 tobj->mesh.vertSel.ClearAll();
1163 nodes.DisposeTemporary();
1168 NotifyDependents(
FOREVER, PART_SELECT, REFMSG_CHANGE);
1176 ModContextList mclist;
1184 for (
int i = 0; i < mclist.Count(); i++) {
1188 if (skindata==
NULL)
continue;
1190 ObjectState os = nodes[i]->EvalWorldState(
InterfacePtr->GetTime());
1191 TriObject * tobj = Get_Tri_Object(
InterfacePtr->GetTime(),os,valid,needsdel);
1201 if (theHold.Holding()) {
1202 theHold.Put(
new VertexSelRestore(meshData,
this));
1205 tobj->mesh.vertSel.SetAll();
1218 nodes.DisposeTemporary();
1223 NotifyDependents(
FOREVER, PART_SELECT, REFMSG_CHANGE);
1230 ModContextList mclist;
1238 for (
int i = 0; i < mclist.Count(); i++) {
1242 if (skindata==
NULL)
continue;
1244 ObjectState os = nodes[i]->EvalWorldState(
InterfacePtr->GetTime());
1245 TriObject * tobj = Get_Tri_Object(
InterfacePtr->GetTime(),os,valid,needsdel);
1255 if (theHold.Holding()) {
1256 theHold.Put(
new VertexSelRestore(meshData,
this));
1259 for (
int j=0; j<tobj->mesh.vertSel.GetSize(); j++) {
1260 if (tobj->mesh.vertSel[j]) tobj->mesh.vertSel.Clear(j);
1261 else tobj->mesh.vertSel.Set(j);
1263 skindata->
VertSel = tobj->mesh.vertSel;
1275 nodes.DisposeTemporary();
1280 NotifyDependents(
FOREVER, PART_SELECT, REFMSG_CHANGE);
1292 ModContext * mc =
NULL;
1293 ModContextList mclist;
1312 assert(boneidx != -1);
1323 NotifyDependents(
FOREVER, PART_ALL, REFMSG_CHANGE);
1333 for (
int i=0; i<nodetab.Count() && i<2; i++) {
1340 ModContextList mclist;
1347 for (
int i = 0; i < mclist.Count(); i++) {
1350 if (!skindata)
continue;
1353 if (index < 0)
continue;
1357 ObjectState os = nodes[i]->EvalWorldState(
InterfacePtr->GetTime());
1358 TriObject * tobj = Get_Tri_Object(
InterfacePtr->GetTime(),os,valid,needsdel);
1359 Mesh * mesh = &(tobj->mesh);
1363 if (theHold.Holding()) {
1364 theHold.Put(
new VertexSelRestore(meshData,
this));
1368 if (skindata->
VertSelSets[index].GetSize() != mesh->getNumVerts()) {
1372 skindata->
VertSel = mesh->vertSel;
1379 nodes.DisposeTemporary();
1381 NotifyDependents(
FOREVER, PART_SELECT, REFMSG_CHANGE);
1404 if (skinobj ==
NULL)
return;
1406 ModContextList mclist;
1410 if (skindata ==
NULL)
return;
1420 for (
int boneidx = 0; boneidx < skinobj->
Num_Bones(); boneidx++) {
1424 boneverts.SetSize(skindata->
VertData.Count());
1426 for (
int vertidx = 0; vertidx < skindata->
VertData.Count(); vertidx++) {
1427 if (skindata->
VertData[vertidx].BoneIdx[0] == boneidx) boneverts.Set(vertidx);
1428 else boneverts.Clear(vertidx);
1431 TSTR bonename = skinobj->
Get_Bone(boneidx)->GetName();
1439 nodes.DisposeTemporary();
1450 ModContextList mclist;
1454 if (skindata ==
NULL)
return;
1461 nodes.DisposeTemporary();
1472 ModContextList mclist;
1476 if (skindata ==
NULL)
return;
1482 if (skinobj ==
NULL)
return;
1490 TimeValue basetime =
WSMObjectRef->Get_Base_Pose_Time();
1491 ObjectState os = nodes[0]->EvalWorldState(basetime);
1492 TriObject * triobj = Get_Tri_Object(basetime,os,valid,needsdel);
1497 for (
int vertidx = 0; vertidx < skindata->
VertData.Count(); vertidx++){
1498 if (skindata->
VertSel[vertidx] || all) {
1500 Point3 vert = triobj->GetPoint(vertidx);
1501 if (os.GetTM()) vert = vert * (*os.GetTM());
1503 skindata->
VertData[vertidx].Set_Influence(boneidx);
1515 NotifyDependents(
FOREVER, PART_ALL, REFMSG_CHANGE);
1521 nodes.DisposeTemporary();
1524 triobj->DeleteThis();
1535 ModContextList mclist;
1539 if (skindata ==
NULL)
return;
1544 for (
int vertidx = 0; vertidx < skindata->
VertData.Count(); vertidx++){
1545 if (skindata->
VertSel[vertidx]) {
1546 skindata->
VertData[vertidx].Set_Influence(-1);
1558 NotifyDependents(
FOREVER, PART_ALL, REFMSG_CHANGE);
1564 nodes.DisposeTemporary();
1574void SkinModifierClass::Install_Bone_Influence_Dialog(
void)
1581 static int loaded = 0;
1601void SkinModifierClass::Remove_Bone_Influence_Dialog(
void)
1618static BOOL CALLBACK _sot_dialog_proc(HWND hWnd,
UINT message,WPARAM wParam,LPARAM lParam)
1620 IObjParam *ip = (IObjParam*)GetWindowLong(hWnd,GWL_USERDATA);
1624 SetWindowLong(hWnd,GWL_USERDATA,lParam);
1627 case WM_LBUTTONDOWN:
1630 if (ip) ip->RollupMouseMessage(hWnd,message,wParam,lParam);
1648 if (!skinobj && message != WM_INITDIALOG)
return FALSE;
1650 if (message == WM_INITDIALOG) {
1652 SetWindowLong(hWnd,GWL_USERDATA,(LONG)skinobj);
1702 case CC_SPINNER_CHANGE:
1703 switch (LOWORD(wParam))
1709 NotifyDependents(
FOREVER, PART_ALL, REFMSG_CHANGE);
1713 case CC_SPINNER_BUTTONUP:
1714 NotifyDependents(
FOREVER, PART_ALL, REFMSG_CHANGE);
1719 case WM_LBUTTONDOWN:
1722 InterfacePtr->RollupMouseMessage(hWnd,message,wParam,lParam);
1726 switch (LOWORD(wParam))
1757 if (!skinmod && message != WM_INITDIALOG)
return FALSE;
1759 if (message == WM_INITDIALOG) {
1761 SetWindowLong(hWnd,GWL_USERDATA,(LONG)skinmod);
1764 return skinmod->Bone_Influence_Dialog_Proc(hWnd,message,wParam,lParam);
1768BOOL SkinModifierClass::Bone_Influence_Dialog_Proc(HWND hWnd,
UINT message,WPARAM wParam,LPARAM lParam)
1782 LinkButton->SetTooltip(
TRUE, _T(
"Link Vertices to a bone by selecting the bone"));
1807 case WM_LBUTTONDOWN:
1810 InterfacePtr->RollupMouseMessage(hWnd,message,wParam,lParam);
1814 switch (LOWORD(wParam))
1858static TriObject * Get_Tri_Object(TimeValue t,ObjectState & os,Interval & valid,
BOOL & needsdel)
1861 valid &= os.Validity(t);
1863 if (os.obj->IsSubClassOf(triObjectClassID)) {
1864 return (TriObject *)os.obj;
1866 if (os.obj->CanConvertToType(triObjectClassID)) {
1867 Object * oldObj = os.obj;
1868 TriObject * tobj = (TriObject *)os.obj->ConvertToType(t,triObjectClassID);
1869 needsdel = (tobj != oldObj);
1877float Bone_Distance(INode * bone,TimeValue time,
const Point3 & vertex)
1883 Point3 icenter = bone->GetObjectTM(time).GetTrans();
1885 for (
int ci=0; ci<bone->NumberOfChildren(); ci++) {
1886 icenter += bone->GetChildNode(ci)->GetObjectTM(time).GetTrans();
1889 icenter = icenter / (float)(bone->NumberOfChildren() + 1);
1891 return Length(icenter - vertex);
1896int SkinModifierClass::NumSubObjTypes()
1901ISubObjType *SkinModifierClass::GetSubObjType(
int i)
1904 static bool _initialized =
false;
1906 _initialized =
true;
1907 _SubObjectTypeVertex.SetName(
"Vertices");
1910 if(GetSubObjectLevel() > 0){
1911 return GetSubObjType(GetSubObjectLevel()-1);
1914 return &_SubObjectTypeVertex;
const int NumBoneIconFaces
VertexStruct BoneIconVerts[NumBoneIconVerts]
FaceStruct BoneIconFaces[NumBoneIconFaces]
const int NumBoneIconVerts
BonePickerClass TheBonePicker
void Set_User(BonePickerUserClass *user, int singlepick=FALSE, INodeTab *bonelist=NULL)
int Find_Set(TSTR &setname)
void Append_Set(BitArray &nset, TSTR &setname)
NamedSelSetList VertSelSets
void Add_Influence(int boneidx)
Tab< InfluenceStruct > VertData
IOResult Load(ILoad *iload)
IOResult Save(ISave *isave)
void Validate(Mesh *mesh)
void * Create(BOOL loading=FALSE)
const TCHAR * ClassName()
virtual void User_Picked_Bones(INodeTab &nodetab)
void Create_Named_Selection_Sets(void)
void EndEditParams(IObjParam *ip, ULONG flags, Animatable *next)
void InvertSelection(int selLevel)
void BeginEditParams(IObjParam *ip, ULONG flags, Animatable *prev)
void SetReference(int i, RefTargetHandle rtarg)
virtual void ActivateSubSelSet(TSTR &setName)
void Install_Named_Selection_Sets(void)
virtual void RemoveSubSelSet(TSTR &setName)
virtual void NewSetFromCurSel(TSTR &setName)
SelectModBoxCMode * SelectMode
RefTargetHandle Clone(RemapDir &remap=NoRemap())
RefTargetHandle GetReference(int i)
void SelectSubComponent(HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert=FALSE)
ICustButton * LinkByNameButton
friend BOOL CALLBACK _bone_influence_dialog_thunk(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
SkinWSMObjectClass * WSMObjectRef
WSMObject * Get_WSMObject(void)
virtual IOResult SaveLocalData(ISave *isave, LocalModData *ld)
virtual void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node)
Interval Get_Validity(TimeValue t)
virtual IOResult LoadLocalData(ILoad *iload, LocalModData **pld)
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID &partID, RefMessage message)
IOResult Save(ISave *isave)
IOResult Load(ILoad *iload)
ICustButton * UnLinkButton
ICustButton * AutoLinkButton
int HitTest(TimeValue t, INode *inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext *mc)
void SelectAll(int selLevel)
void Auto_Attach_Verts(BOOL all=FALSE)
void ClearSelection(int selLevel)
virtual void User_Picked_Bone(INode *node)
void ActivateSubobjSel(int level, XFormModes &modes)
const TCHAR * ClassName()
void * Create(BOOL loading=FALSE)
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID &partID, RefMessage message)
void Remove_Bone(INode *node)
int Get_Base_Pose_Time(void)
static ISpinnerControl * BasePoseSpin
virtual ~SkinWSMObjectClass()
static ICustButton * RemoveBonesButton
@ BONE_SEL_MODE_REMOVE_MANY
IOResult Save(ISave *isave)
int To_Ref_Index(int boneidx)
virtual void User_Picked_Bone(INode *node)
virtual void SetReference(int i, RefTargetHandle rtarg)
void Set_Bone_Selection_Mode(int mode)
void BeginEditParams(IObjParam *ip, ULONG flags, Animatable *prev)
INodeTab & Get_Bone_List(void)
void Add_Bones(INodeTab &nodetab)
int Find_Closest_Bone(const Point3 &vertex)
Modifier * CreateWSMMod(INode *node)
friend BOOL CALLBACK _skeleton_dialog_thunk(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
void Remove_Bones(INodeTab &nodetab)
BOOL Skeleton_Dialog_Proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
static ICustButton * AddBonesButton
int Add_Bone(INode *node)
int Find_Bone(INode *node)
void BuildMesh(TimeValue t)
void EndEditParams(IObjParam *ip, ULONG flags, Animatable *next)
static IObjParam * InterfacePtr
virtual RefTargetHandle GetReference(int i)
virtual void User_Picked_Bones(INodeTab &nodetab)
IOResult Load(ILoad *iload)
RefTargetHandle Clone(RemapDir &remap=NoRemap())
void Update_Bone_List(void)
INode * Get_Bone(int idx)
int To_Bone_Index(int refidx)
void Build_Tri(Face *f, int a, int b, int c)
CreateMouseCallBack * GetCreateMouseCallBack()
int proc(ViewExp *vpt, int msg, int point, int flags, IPoint2 m, Matrix3 &mat)
TCHAR * Get_String(int id)
#define MAX_STRING_LENGTH
WWINLINE Quaternion Inverse(const Quaternion &a)
ClassDesc * Get_Skin_Mod_Desc()
ClassDesc * Get_Skin_Obj_Desc()
#define SKIN_OBJ_CLASS_ID
#define SKIN_MOD_CLASS_ID