📄 flyfao.cpp
字号:
#include "Max.h"
#include "resource.h"
#include "istdplug.h"
#include "iparamm.h"
#include "flyfao.h"
HINSTANCE hInstance;
int controlsInit = FALSE;
TCHAR *GetString(int id);
extern HINSTANCE hInstance;
IObjParam *Flyfao::ip = NULL;
IParamMap *Flyfao::pmapParam = NULL;
class FlyfaoClassDesc:public ClassDesc {
public:
int IsPublic() {return 1;}
void * Create(BOOL loading = FALSE) {return new Flyfao();}
const TCHAR * ClassName() {return GetString(IDS_CLASS_NAME);}
SClass_ID SuperClassID() {return GEOMOBJECT_CLASS_ID;}
Class_ID ClassID() {return FLYFAO_CLASS_ID;}
const TCHAR* Category() {return GetString(IDS_CATEGORY);}
void ResetClassParams (BOOL fileReset);
};
class flyfaoDlg : public ParamMapUserDlgProc {
public:
Flyfao *ff;
BOOL DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
void DeleteThis() {}
};
class PickControlNode :
public PickModeCallback,
public PickNodeCallback {
public:
Flyfao *ff;
INode *node;
PickControlNode() { ff=NULL; node=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; }
};
class FlyfaoCreateCallBack : public CreateMouseCallBack {
IPoint2 sp0;
Flyfao *ob;
Point3 p0;
public:
int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat);
void SetObj(Flyfao *obj) {ob = obj;}
};
static flyfaoDlg flyfaodlg;
static FlyfaoClassDesc FlyfaoDesc;
static PickControlNode thePickMode;
static FlyfaoCreateCallBack FlyfaoCreateCB;
ClassDesc* GetFlyfaoDesc() { return &FlyfaoDesc; }
#define PB_KEY 0
static ParamUIDesc descParam[] = {
ParamUIDesc(
PB_KEY,
EDITTYPE_INT,
IDC_KEY,IDC_KEY_SPIN,
0,256,
1),
};
#define PARAMDESC_LENGTH 1
static ParamBlockDescID descVer1[] = {
{ TYPE_INT, NULL, TRUE, 0 },
};
#define CURRENT_DESCRIPTOR descVer1
#define PBLOCK_LENGTH 1
#define CURRENT_VERSION 1
BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved)
{
hInstance = hinstDLL;
if (!controlsInit) {
controlsInit = TRUE;
InitCustomControls(hInstance);
InitCommonControls();
}
return (TRUE);
}
__declspec( dllexport ) const TCHAR* LibDescription()
{
return GetString(IDS_LIBDESCRIPTION);
}
__declspec( dllexport ) int LibNumberClasses()
{
return 1;
}
__declspec( dllexport ) ClassDesc* LibClassDesc(int i)
{
switch(i) {
case 0: return GetFlyfaoDesc();
default: return 0;
}
}
__declspec( dllexport ) ULONG LibVersion()
{
return VERSION_3DSMAX;
}
TCHAR *GetString(int id)
{
static TCHAR buf[256];
if (hInstance)
return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL;
return NULL;
}
void FlyfaoClassDesc::ResetClassParams (BOOL fileReset)
{
}
BOOL PickControlNode::Filter(INode *node)
{
node->BeginDependencyTest();
ff->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)
{
node = vpt->GetClosestHit();
if (node)
{
}
return TRUE;
}
void PickControlNode::EnterMode(IObjParam *ip)
{
node=0;
}
void PickControlNode::ExitMode(IObjParam *ip)
{
if (node)
{
Object *obj = node->EvalWorldState(ip->GetTime()).obj;
if(obj->CanConvertToType(triObjectClassID))
{
char *name=node->GetName();
Mesh *mesh=&((TriObject *)obj->ConvertToType(ip->GetTime(),triObjectClassID))->mesh;
Matrix3 piv(1);
piv.PreTranslate(node->GetObjOffsetPos());
PreRotateMatrix(piv, node->GetObjOffsetRot());
ApplyScaling(piv, node->GetObjOffsetScale());
Matrix3 tm=node->GetObjectTM(ip->GetTime());
Point3 pos=tm.GetTrans();
ff->add_key(mesh,tm,pos,piv);
}
}
}
void Flyfao::add_key(Mesh *mesh,Matrix3 tm,Point3 pos, Matrix3 piv)
{
if (nkeys==0)
{
nfaces=mesh->numFaces;
nverts=mesh->numVerts;
verts=new float[nverts*3];
faces=new unsigned short[nfaces*3];
uvs=new float[nfaces*3*2];
int i;
Point3 p;
for( i=0;i<nverts;i++ )
{
p=mesh->verts[i]*piv;
p=p*tm;
p=p-pos;
verts[i*3]=p.x;
verts[i*3+1]=p.y;
verts[i*3+2]=p.z;
}
for( i=0;i<nfaces;i++ )
{
faces[i*3]=(unsigned short)mesh->faces[i].v[0];
faces[i*3+1]=(unsigned short)mesh->faces[i].v[1];
faces[i*3+2]=(unsigned short)mesh->faces[i].v[2];
if (mesh->tVerts)
{
uvs[i*6]=mesh->tVerts[mesh->tvFace[i].t[0]].x;
uvs[i*6+1]=mesh->tVerts[mesh->tvFace[i].t[0]].y;
uvs[i*6+2]=mesh->tVerts[mesh->tvFace[i].t[1]].x;
uvs[i*6+3]=mesh->tVerts[mesh->tvFace[i].t[1]].y;
uvs[i*6+4]=mesh->tVerts[mesh->tvFace[i].t[2]].x;
uvs[i*6+5]=mesh->tVerts[mesh->tvFace[i].t[2]].y;
}
else
uvs[i*6]=uvs[i*6+1]=uvs[i*6+2]=
uvs[i*6+3]=uvs[i*6+4]=uvs[i*6+5]=0;
}
nkeys++;
}
else if (mesh->numVerts==nverts && mesh->numFaces==nfaces)
{
int i,j=nverts*nkeys;
float *tmp=new float[(j+nverts)*3];
memcpy(tmp,verts,sizeof(float)*j*3);
delete verts;
verts=tmp;
Point3 p;
for( i=0;i<nverts;i++ )
{
p=mesh->verts[i]*piv;
p=p*tm;
p=p-pos;
verts[(j+i)*3]=p.x;
verts[(j+i)*3+1]=p.y;
verts[(j+i)*3+2]=p.z;
}
nkeys++;
}
char str[256];
sprintf(str,"Num faces: %i",nfaces);
SetDlgItemText(hParams,IDC_NUMFACES,str);
sprintf(str,"Num verts: %i",nverts);
SetDlgItemText(hParams,IDC_NUMVERTS,str);
sprintf(str,"Total keys: %i",nkeys);
SetDlgItemText(hParams,IDC_NUMKEYS,str);
pblock->SetValue(PB_KEY,0,0);
}
Flyfao::Flyfao()
{
nkeys=0;
nverts=0;
nfaces=0;
verts=0;
uvs=0;
faces=0;
pblock = CreateParameterBlock(
CURRENT_DESCRIPTOR,
PBLOCK_LENGTH,
CURRENT_VERSION);
assert(pblock);
MakeRefByID(FOREVER, 0, pblock);
}
Flyfao::~Flyfao()
{
if (faces) delete faces;
if (verts) delete verts;
if (uvs) delete uvs;
}
#define FAO_DATA_CHUNK 9100
TCHAR *Flyfao::GetObjectName()
{
return GetString(IDS_CLASS_NAME);
}
IOResult Flyfao::Load(ILoad *iload)
{
ULONG nb;
IOResult res;
while (IO_OK==(res=iload->OpenChunk()))
{
switch(iload->CurChunkID())
{
case FAO_DATA_CHUNK:
res=iload->Read(&nkeys,sizeof(int),&nb);
res=iload->Read(&nfaces,sizeof(int),&nb);
res=iload->Read(&nverts,sizeof(int),&nb);
if (nfaces)
{
verts=new float[nkeys*nverts*3];
faces=new unsigned short[nfaces*3];
uvs=new float[nfaces*3*2];
res=iload->Read(faces,nfaces*3*sizeof(unsigned short),&nb);
res=iload->Read(uvs,nfaces*3*2*sizeof(float),&nb);
res=iload->Read(verts,nkeys*nverts*3*sizeof(float),&nb);
}
break;
}
iload->CloseChunk();
if (res!=IO_OK)
return res;
}
return IO_OK;
}
IOResult Flyfao::Save(ISave *isave)
{
ULONG nb;
isave->BeginChunk(FAO_DATA_CHUNK);
isave->Write(&nkeys,sizeof(int),&nb);
isave->Write(&nfaces,sizeof(int),&nb);
isave->Write(&nverts,sizeof(int),&nb);
isave->Write(faces,nfaces*3*sizeof(unsigned short),&nb);
isave->Write(uvs,nfaces*3*2*sizeof(float),&nb);
isave->Write(verts,nkeys*nverts*3*sizeof(float),&nb);
isave->EndChunk();
return IO_OK;
}
int Flyfao::load_fao(char *file)
{
if (faces) delete faces;
if (verts) delete verts;
if (uvs) delete uvs;
nkeys=0;
nverts=0;
nfaces=0;
verts=0;
uvs=0;
faces=0;
FILE *fp=fopen(file,"rb");
if (fp)
{
int i,j;
char skin[64];
float pivotpos[3];
fread(&i,1,sizeof(int),fp);
if (i!=9171)
{
fclose(fp);
return 0;
}
fread(&nfaces,1,sizeof(int),fp);
fread(&nverts,1,sizeof(int),fp);
fread(&nkeys,1,sizeof(int),fp);
fread(&pivotpos,3,sizeof(float),fp);
fread(skin,1,64,fp);
verts=new float[nverts*nkeys*3];
uvs=new float[6*nfaces];
faces=new unsigned short[3*nfaces];
fread(faces,nfaces,sizeof(unsigned short)*3,fp);
fread(uvs,nfaces,sizeof(float)*6,fp);
fread(verts,nverts*nkeys,sizeof(float)*3,fp);
fclose(fp);
float fac=(float)GetMasterScale(UNITS_CENTIMETERS)/10;
j=nverts*nkeys*3;
for( i=0;i<j;i++ )
{
verts[i]/=fac;
}
return 1;
}
return 0;
}
int Flyfao::save_fao(char *file,char *skin,Point3 pivot)
{
FILE *fp=fopen(file,"wb");
if (fp)
{
int i=9171,j;
char skinfile[64];
float fac=(float)GetMasterScale(UNITS_CENTIMETERS)/10,f;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -