# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

rpo.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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 //TODO: Add enums for various parameters
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 // RPO ------------------------------------------------------------------------------------------------------------------------------------------------
00093 
00094 RPO::RPO()
00095 {
00096         RPODesc.MakeAutoParamBlocks(this);
00097         bBigHack=false;
00098 
00099         rpatch = NULL;
00100 
00101         // Infinite
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         //Mode=ModeRykolPatchMesh;
00116         bBigHack=false;
00117 
00118         // Infinite
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         //RPODesc.BeginEditParams(ip, this, flags, prev);
00143         //PatchObject::BeginEditParams(ip, flags, prev);
00144 }
00145 
00146 // ------------------------------------------------------------------------------------------------------------------------------------------------
00147 
00148 void RPO::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
00149 {
00150         //TODO: Save plugin parameter values into class variables, if they are not hosted in ParamBlocks. 
00151         
00152 
00153         //RPODesc.EndEditParams(ip, this, flags, next);
00154         this->ip = NULL;
00155         //PatchObject::EndEditParams(ip, flags, next);
00156 }
00157 
00158 // ------------------------------------------------------------------------------------------------------------------------------------------------
00159 
00160 //From Object
00161 BOOL RPO::HasUVW() 
00162 { 
00163         //TODO: Return whether the object has UVW coordinates or not
00164         return TRUE; 
00165 }
00166 
00167 // ------------------------------------------------------------------------------------------------------------------------------------------------
00168 
00169 void RPO::SetGenUVW(BOOL sw) 
00170 {  
00171         if (sw==HasUVW()) return;
00172         //TODO: Set the plugin's internal value to sw                           
00173 }
00174 
00175 // ------------------------------------------------------------------------------------------------------------------------------------------------
00176 
00177 //Class for interactive creation of the object using the mouse
00178 class RPOCreateCallBack : public CreateMouseCallBack 
00179 {
00180         IPoint2 sp0;            //First point in screen coordinates
00181         RPO *ob;                //Pointer to the object 
00182         Point3 p0;                      //First point in world coordinates
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         //TODO: Implement the mouse creation code here
00196         if (msg==MOUSE_POINT||msg==MOUSE_MOVE) 
00197         {
00198                 switch(point) 
00199                 {
00200                 case 0: // only happens with MOUSE_POINT msg
00201                         ob->suspendSnap = TRUE;
00202                         sp0 = m;
00203                         p0 = vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE);
00204                         mat.SetTrans(p0);
00205                         break;
00206                 //TODO: Add for the rest of points
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 //From BaseObject
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         //TODO: Implement the displaying of the object here
00235         if (!rpatch->rTess.ModeTile)
00236         {
00237                 int ret= PatchObject::Display(t, inode, vpt, flags);
00238 
00239                 // Point binded
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                                         // draw the point
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         //TODO: Implement the hit testing here
00269         return PatchObject::HitTest(t, inode, type, crossing, flags, p, vpt);
00270         //return 0;
00271 }
00272 
00273 // ------------------------------------------------------------------------------------------------------------------------------------------------
00274 
00275 void RPO::Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt)
00276 {
00277         //TODO: Check the point passed for a snap and update the SnapInfo structure
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         //TODO: Return the world space bounding box of the object
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         //TODO: Return the local space bounding box of the object
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         //TODO: Compute the bounding box in the objects local coordinates 
00302         //              or the optional space defined by tm.
00303         PatchObject::GetDeformBBox(t, box, tm, useSel);
00304 }
00305 
00306 // ------------------------------------------------------------------------------------------------------------------------------------------------
00307 
00308 //From ReferenceMaker
00309 RefResult RPO::NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget,PartID& partID, RefMessage message )
00310 {
00311         //TODO: Implement, if the object makes references to other things
00312         //return PatchObject::NotifyRefChanged( changeInt, hTarget, partID, message);
00313         return(REF_SUCCEED);
00314 }
00315 
00316 // ------------------------------------------------------------------------------------------------------------------------------------------------
00317 
00318 Mesh* RPO::GetRenderMesh(TimeValue t, INode *inode, View& view, BOOL& needDelete)
00319 {
00320         //TODO: Return the mesh representation of the object used by the renderer
00321         needDelete=TRUE;
00322         Mesh *pMesh=new Mesh();
00323         rpatch->BuildMesh(t, patch, pMesh);
00324         return pMesh;
00325 }
00326 
00327 // ------------------------------------------------------------------------------------------------------------------------------------------------
00328 
00329 /*
00330   Lire doc intervals
00331   Ici : conversion d'un RPM en n'importe kwa : triObj, PO
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 // From Object
00378 int RPO::IntersectRay(TimeValue t, Ray& ray, float& at, Point3& norm)
00379 {
00380         //TODO: Return TRUE after you implement this method
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         //TODO: Append any any other collapse type the plugin supports
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 // From ReferenceTarget
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         //PatchObject::Save(isave);
00423 
00424         // Version
00425         isave->BeginChunk(VALIDITY_CHUNK);
00426 
00427         unsigned int nVersion=RPO_SERIALIZE_VERSION;
00428         isave->Write(&nVersion, sizeof (nVersion), &nb);
00429 
00430         // RPatch
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                         // Version
00454                         unsigned int nVersion;
00455                         iload->Read(&nVersion, sizeof (nVersion), &nb);
00456 
00457                         switch (nVersion)
00458                         {
00459                         case RPO_SERIALIZE_VERSION:
00460                                 // RPatch
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         // Copy patch mesh
00484         newob->patch.ShallowCopy(&patch, channels);
00485 
00486         // Copy validity
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         // Copy rpatch mesh
00499         if (channels&PART_TOPO)
00500                 rpatch=fromRPO->rpatch;
00501 
00502         // Copy patch mesh
00503         patch.ShallowCopy(&fromRPO->patch, channels);
00504 
00505         // Copy validity
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         //PatchObject::InvalidateChannels(channels);
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                                 //case VERT_COLOR_CHAN_NUM: vcolorValid.SetEmpty(); break;
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                                 //case GFX_DATA_CHAN_NUM: gfxdataValid.SetEmpty(); break;
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         // Result false by default
00573         bool bRet=false;
00574 
00575         // Eval the object a time
00576         ObjectState os = node.EvalWorldState(time);
00577 
00578         // Object exist ?
00579         if (os.obj)
00580         {
00581                 // Object can convert itself to NeL patchmesh ?
00582                 if (os.obj->CanConvertToType(RYKOLPATCHOBJ_CLASS_ID))
00583                         bRet=true;
00584         }
00585 
00586         // Return result
00587         return bRet;
00588 }
00589 
00590 // --------------------------------------------------
00591