00001
00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024
00025
00026 #include "stdafx.h"
00027 #include "rpo.h"
00028
00029 using namespace NL3D;
00030
00031 #ifndef max
00032 #define max(a,b) (((a) > (b)) ? (a) : (b))
00033 #endif max
00034
00035 #define PBLOCK_REF 0
00036
00037 #ifdef USE_CACHE
00038 #ifndef NDEBUG
00039 #define DEBUG_PIPELINE
00040 #endif // NDEBUG
00041 #endif // USE_CACHE
00042
00043
00044 class RPOClassDesc:public ClassDesc
00045 {
00046 public:
00047 int IsPublic()
00048 {
00049 return 0;
00050 }
00051 void * Create(BOOL loading = FALSE)
00052 {
00053 return new RPO;
00054 }
00055 const TCHAR * ClassName()
00056 {
00057 return "RklPatch";
00058 }
00059 SClass_ID SuperClassID()
00060 {
00061 return GEOMOBJECT_CLASS_ID;
00062 }
00063 Class_ID ClassID()
00064 {
00065 return RYKOLPATCHOBJ_CLASS_ID;
00066 }
00067 const TCHAR* Category()
00068 {
00069 return "Rykol Tools";
00070 }
00071 };
00072
00073
00074 enum { RPO_params };
00075
00076
00077 enum { pb_spin };
00078
00079 IObjParam *RPO::ip = NULL;
00080
00081 BOOL RPO::attachMat=FALSE;
00082 BOOL RPO::condenseMat=FALSE;
00083
00084
00085 static RPOClassDesc RPODesc;
00086
00087 ClassDesc* GetRPODesc()
00088 {
00089 return &RPODesc;
00090 }
00091
00092
00093
00094 RPO::RPO()
00095 {
00096 RPODesc.MakeAutoParamBlocks(this);
00097 bBigHack=false;
00098
00099 rpatch = NULL;
00100
00101
00102 topoValid.SetInfinite();
00103 geomValid.SetInfinite();
00104 selectValid.SetInfinite();
00105 texmapValid.SetInfinite();
00106 validBits = 0xffffffff;
00107 }
00108
00109 RPO::RPO(PatchObject& pPO) : PatchObject(pPO)
00110 {
00111 RPODesc.MakeAutoParamBlocks(this);
00112
00113 rpatch = new RPatchMesh (&pPO.patch);
00114
00115
00116 bBigHack=false;
00117
00118
00119 topoValid.SetInfinite();
00120 geomValid.SetInfinite();
00121 selectValid.SetInfinite();
00122 texmapValid.SetInfinite();
00123 validBits = 0xffffffff;
00124 }
00125
00126
00127
00128 RPO::~RPO()
00129 {
00130 if (((~GetChannelLocks()))&PART_TOPO)
00131 {
00132 delete rpatch;
00133 rpatch=NULL;
00134 }
00135 }
00136
00137
00138
00139 void RPO::BeginEditParams(IObjParam *ip,ULONG flags,Animatable *prev)
00140 {
00141 this->ip = ip;
00142
00143
00144 }
00145
00146
00147
00148 void RPO::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
00149 {
00150
00151
00152
00153
00154 this->ip = NULL;
00155
00156 }
00157
00158
00159
00160
00161 BOOL RPO::HasUVW()
00162 {
00163
00164 return TRUE;
00165 }
00166
00167
00168
00169 void RPO::SetGenUVW(BOOL sw)
00170 {
00171 if (sw==HasUVW()) return;
00172
00173 }
00174
00175
00176
00177
00178 class RPOCreateCallBack : public CreateMouseCallBack
00179 {
00180 IPoint2 sp0;
00181 RPO *ob;
00182 Point3 p0;
00183 public:
00184 int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat);
00185 void SetObj(RPO *obj)
00186 {
00187 ob = obj;
00188 }
00189 };
00190
00191
00192
00193 int RPOCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat )
00194 {
00195
00196 if (msg==MOUSE_POINT||msg==MOUSE_MOVE)
00197 {
00198 switch(point)
00199 {
00200 case 0:
00201 ob->suspendSnap = TRUE;
00202 sp0 = m;
00203 p0 = vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE);
00204 mat.SetTrans(p0);
00205 break;
00206
00207 }
00208 }
00209 else
00210 {
00211 if (msg == MOUSE_ABORT)
00212 {
00213 return CREATE_ABORT;
00214 }
00215 }
00216 return TRUE;
00217 }
00218
00219
00220
00221 static RPOCreateCallBack RPOCreateCB;
00222
00223
00224 CreateMouseCallBack* RPO::GetCreateMouseCallBack()
00225 {
00226 RPOCreateCB.SetObj(this);
00227 return(&RPOCreateCB);
00228 }
00229
00230
00231
00232 int RPO::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags)
00233 {
00234
00235 if (!rpatch->rTess.ModeTile)
00236 {
00237 int ret= PatchObject::Display(t, inode, vpt, flags);
00238
00239
00240 if (inode->Selected())
00241 {
00242 GraphicsWindow *gw = vpt->getGW();
00243 gw->setColor(LINE_COLOR, 0, 0, 0);
00244 for (int i=0; i<patch.numVerts; i++)
00245 {
00246 if (rpatch->getUIVertex (i).Binding.bBinded)
00247 {
00248
00249 gw->marker (&patch.verts[i].p, DOT_MRKR);
00250 }
00251 }
00252 }
00253
00254 return ret;
00255
00256 }
00257 else
00258 {
00259 return rpatch->Display (t, inode, vpt, flags, patch);
00260 }
00261 }
00262
00263
00264
00265 int RPO::HitTest(TimeValue t, INode* inode, int type, int crossing,
00266 int flags, IPoint2 *p, ViewExp *vpt)
00267 {
00268
00269 return PatchObject::HitTest(t, inode, type, crossing, flags, p, vpt);
00270
00271 }
00272
00273
00274
00275 void RPO::Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt)
00276 {
00277
00278 PatchObject::Snap(t, inode, snap, p, vpt);
00279 }
00280
00281
00282
00283 void RPO::GetWorldBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box )
00284 {
00285
00286 PatchObject::GetWorldBoundBox(t, mat, vpt, box);
00287 }
00288
00289
00290
00291 void RPO::GetLocalBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box )
00292 {
00293
00294 PatchObject::GetLocalBoundBox(t, mat, vpt, box);
00295 }
00296
00297
00298
00299 void RPO::GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm, BOOL useSel )
00300 {
00301
00302
00303 PatchObject::GetDeformBBox(t, box, tm, useSel);
00304 }
00305
00306
00307
00308
00309 RefResult RPO::NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget,PartID& partID, RefMessage message )
00310 {
00311
00312
00313 return(REF_SUCCEED);
00314 }
00315
00316
00317
00318 Mesh* RPO::GetRenderMesh(TimeValue t, INode *inode, View& view, BOOL& needDelete)
00319 {
00320
00321 needDelete=TRUE;
00322 Mesh *pMesh=new Mesh();
00323 rpatch->BuildMesh(t, patch, pMesh);
00324 return pMesh;
00325 }
00326
00327
00328
00329 00330 00331 00332 00333
00334 Object* RPO::ConvertToType(TimeValue t, Class_ID cid)
00335 {
00336 if (cid==RYKOLPATCHOBJ_CLASS_ID)
00337 {
00338 return this;
00339 }
00340 if (cid==defObjectClassID)
00341 {
00342 return this;
00343 }
00344 if (cid==triObjectClassID)
00345 {
00346 TriObject *pTriObj=CreateNewTriObject();
00347 rpatch->InvalidateChannels (PART_TOPO|PART_GEOM|PART_TEXMAP|PART_SELECT|PART_DISPLAY);
00348 rpatch->BuildMesh(t, patch, &pTriObj->mesh);
00349 pTriObj->SetChannelValidity(TOPO_CHAN_NUM,ConvertValidity(t));
00350 pTriObj->SetChannelValidity(GEOM_CHAN_NUM,ConvertValidity(t));
00351 return pTriObj;
00352 }
00353 return NULL;
00354 }
00355
00356
00357
00358 int RPO::CanConvertToType(Class_ID cid)
00359 {
00360 if (cid==RYKOLPATCHOBJ_CLASS_ID)
00361 {
00362 return 1;
00363 }
00364 if (cid==defObjectClassID)
00365 {
00366 return 1;
00367 }
00368 if (cid==triObjectClassID)
00369 {
00370 return 1;
00371 }
00372 return(0);
00373 }
00374
00375
00376
00377
00378 int RPO::IntersectRay(TimeValue t, Ray& ray, float& at, Point3& norm)
00379 {
00380
00381 return PatchObject::IntersectRay( t, ray, at, norm);
00382 }
00383
00384
00385
00386 void RPO::GetCollapseTypes(Tab<Class_ID> &clist,Tab<TSTR*> &nlist)
00387 {
00388 Object::GetCollapseTypes(clist, nlist);
00389
00390
00391 Class_ID id = RYKOLPATCHOBJ_CLASS_ID;
00392 TSTR *name = new TSTR("Rykol Patch Mesh");
00393 clist.Append(1,&id);
00394 nlist.Append(1,&name);
00395 }
00396
00397
00398
00399
00400 RefTargetHandle RPO::Clone(RemapDir& remap)
00401 {
00402 RPO* newob = new RPO();
00403 newob->rpatch=new RPatchMesh ();
00404 *newob->rpatch=*rpatch;
00405 newob->rpatch->selLevel=EP_OBJECT;
00406 newob->rpatch->InvalidateChannels(ALL_CHANNELS);
00407 newob->patch.DeepCopy(&patch, ALL_CHANNELS);
00408 newob->patch.SetShowInterior(patch.GetShowInterior());
00409
00410 return(newob);
00411 }
00412
00413
00414
00415 #define CHK_TEST 0x0001
00416 #define VALIDITY_CHUNK 2301
00417 static int counter;
00418 IOResult RPO::Save(ISave *isave)
00419 {
00420 ULONG nb;
00421
00422
00423
00424
00425 isave->BeginChunk(VALIDITY_CHUNK);
00426
00427 unsigned int nVersion=RPO_SERIALIZE_VERSION;
00428 isave->Write(&nVersion, sizeof (nVersion), &nb);
00429
00430
00431 rpatch->Save (isave);
00432
00433 isave->EndChunk();
00434 patch.Save (isave);
00435 rpatch->mesh.Save (isave);
00436
00437 return IO_OK;
00438 }
00439
00440
00441
00442 IOResult RPO::Load(ILoad *iload)
00443 {
00444 ULONG nb;
00445
00446 if (rpatch==NULL)
00447 rpatch=new RPatchMesh ();
00448
00449 if (IO_OK==(iload->OpenChunk()))
00450 {
00451 if (iload->CurChunkID()==VALIDITY_CHUNK)
00452 {
00453
00454 unsigned int nVersion;
00455 iload->Read(&nVersion, sizeof (nVersion), &nb);
00456
00457 switch (nVersion)
00458 {
00459 case RPO_SERIALIZE_VERSION:
00460
00461 rpatch->Load (iload);
00462 break;
00463 }
00464
00465 }
00466 iload->CloseChunk();
00467 }
00468 patch.Load (iload);
00469 rpatch->mesh.Load (iload);
00470
00471 return IO_OK;
00472 }
00473
00474
00475
00476 Object *RPO::MakeShallowCopy(ChannelMask channels)
00477 {
00478 RPO* newob=(RPO*)RPODesc.Create();
00479
00480 if (channels&PART_TOPO)
00481 newob->rpatch=rpatch;
00482
00483
00484 newob->patch.ShallowCopy(&patch, channels);
00485
00486
00487 newob->CopyValidity(this,channels);
00488
00489 return newob;
00490 }
00491
00492
00493
00494 void RPO::ShallowCopy(Object* fromOb, ChannelMask channels)
00495 {
00496 RPO* fromRPO=(RPO*)fromOb;
00497
00498
00499 if (channels&PART_TOPO)
00500 rpatch=fromRPO->rpatch;
00501
00502
00503 patch.ShallowCopy(&fromRPO->patch, channels);
00504
00505
00506 CopyValidity(fromRPO, channels);
00507 }
00508
00509
00510
00511 void RPO::NewAndCopyChannels(ChannelMask channels)
00512 {
00513 if (channels&PART_TOPO)
00514 {
00515 RPatchMesh* old=rpatch;
00516 rpatch=new RPatchMesh ();
00517 *rpatch=*old;
00518 }
00519 PatchObject::NewAndCopyChannels(channels);
00520 }
00521
00522
00523
00524 void RPO::FreeChannels(ChannelMask channels)
00525 {
00526 if ((channels&(~GetChannelLocks()))&PART_TOPO)
00527 {
00528 delete rpatch;
00529 rpatch=NULL;
00530 }
00531 PatchObject::FreeChannels(channels);
00532 }
00533
00534
00535
00536 void RPO::InvalidateChannels(ChannelMask channels)
00537 {
00538
00539 if (rpatch)
00540 rpatch->InvalidateChannels(channels);
00541
00542 for (int i=0; i<NUM_OBJ_CHANS; i++)
00543 {
00544 if (channels&chMask[i])
00545 {
00546 switch(i)
00547 {
00548 case GEOM_CHAN_NUM: geomValid.SetEmpty(); break;
00549
00550 case TOPO_CHAN_NUM: topoValid.SetEmpty(); break;
00551 case TEXMAP_CHAN_NUM: texmapValid.SetEmpty(); break;
00552 case SELECT_CHAN_NUM: selectValid.SetEmpty(); break;
00553
00554 default: validBits &= ~chMask[i]; break;
00555 }
00556 }
00557 }
00558 }
00559
00560
00561
00562 void RPO::PointsWereChanged()
00563 {
00564 PatchObject::PointsWereChanged();
00565 rpatch->InvalidateBindingPos ();
00566 }
00567
00568
00569
00570 bool RPO::isZone (INode& node, TimeValue time)
00571 {
00572
00573 bool bRet=false;
00574
00575
00576 ObjectState os = node.EvalWorldState(time);
00577
00578
00579 if (os.obj)
00580 {
00581
00582 if (os.obj->CanConvertToType(RYKOLPATCHOBJ_CLASS_ID))
00583 bRet=true;
00584 }
00585
00586
00587 return bRet;
00588 }
00589
00590
00591