2016-07-25 16:27:53 +00:00
|
|
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as
|
|
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
#ifndef __RYKOL_PATCH_OBJ_H
|
|
|
|
#define __RYKOL_PATCH_OBJ_H
|
|
|
|
|
|
|
|
#pragma warning (disable : 4786)
|
|
|
|
#include "nel/misc/debug.h"
|
|
|
|
#include <tchar.h>
|
|
|
|
#include <vector>
|
|
|
|
#include <set>
|
|
|
|
#include <string>
|
|
|
|
#include "nel/3d/tile_bank.h"
|
|
|
|
#include "nel/misc/file.h"
|
|
|
|
#include "nel_patch_mesh.h"
|
|
|
|
|
|
|
|
//#define USE_CACHE
|
|
|
|
|
|
|
|
typedef unsigned int uint;
|
|
|
|
|
|
|
|
#define RYKOLPATCHOBJ_CLASS_ID Class_ID(0x368c679f, 0x711c22ee)
|
|
|
|
|
|
|
|
extern TCHAR *GetString(int id);
|
|
|
|
|
|
|
|
extern HINSTANCE hInstance;
|
|
|
|
|
|
|
|
#define RPO_SERIALIZE_VERSION 0
|
|
|
|
|
|
|
|
#define EP_OBJECT 0
|
|
|
|
#define EP_VERTEX 1
|
|
|
|
#define EP_EDGE 2
|
|
|
|
#define EP_PATCH 3
|
|
|
|
#define EP_TILE 4
|
|
|
|
|
|
|
|
#define PO_TILE 4
|
|
|
|
|
|
|
|
#define PATCH_HIT_TILE (PATCH_HIT_INTERIOR+1)
|
|
|
|
|
|
|
|
#define MAX_TILE_IN_PATCH 16
|
|
|
|
#define NUM_TILE_SEL (MAX_TILE_IN_PATCH*MAX_TILE_IN_PATCH)
|
|
|
|
|
|
|
|
#pragma warning (disable : 4786)
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class RPO : public PatchObject
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// PatchObject PO;
|
|
|
|
RPatchMesh *rpatch; // User info for this RykolPatchObject
|
|
|
|
|
|
|
|
// bug hack
|
|
|
|
bool bBigHack;
|
|
|
|
|
|
|
|
// Validity
|
|
|
|
Interval topoValid;
|
|
|
|
Interval geomValid;
|
|
|
|
Interval selectValid;
|
|
|
|
Interval texmapValid;
|
|
|
|
/*Interval vcolorValid;
|
|
|
|
Interval gfxdataValid;*/
|
|
|
|
DWORD validBits; // for the remaining constant channels
|
|
|
|
|
|
|
|
//Class vars
|
|
|
|
static IObjParam *ip; //Access to the interface
|
|
|
|
BOOL suspendSnap; //A flag for setting snapping on/off
|
|
|
|
// From BaseObject
|
|
|
|
CreateMouseCallBack* GetCreateMouseCallBack();
|
|
|
|
int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags);
|
|
|
|
int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt);
|
|
|
|
void Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt);
|
|
|
|
//TODO: Return the name that will appear in the history browser (modifier stack)
|
2016-12-02 16:20:25 +00:00
|
|
|
const MCHAR *GetObjectName() { return _M("Rykol Patch Object");}
|
2016-07-25 16:27:53 +00:00
|
|
|
|
|
|
|
void GetWorldBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box );
|
|
|
|
void GetLocalBoundBox(TimeValue t, INode *mat, ViewExp *vpt, Box3& box );
|
|
|
|
|
|
|
|
void GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm, BOOL useSel );
|
|
|
|
//TODO: Return the default name of the node when it is created.
|
2016-12-02 16:20:25 +00:00
|
|
|
void InitNodeName(TSTR& s) { s = _M("Rykol Patch Object"); }
|
2016-07-25 16:27:53 +00:00
|
|
|
|
|
|
|
// From Object
|
|
|
|
BOOL HasUVW();
|
|
|
|
void SetGenUVW(BOOL sw);
|
|
|
|
int CanConvertToType(Class_ID obtype);
|
|
|
|
Object* ConvertToType(TimeValue t, Class_ID obtype);
|
|
|
|
void GetCollapseTypes(Tab<Class_ID> &clist,Tab<TSTR*> &nlist);
|
|
|
|
int IntersectRay(TimeValue t, Ray& ray, float& at, Point3& norm);
|
|
|
|
void PointsWereChanged();
|
|
|
|
|
|
|
|
//TODO: Evaluate the object and return the ObjectState
|
|
|
|
ObjectState Eval(TimeValue t)
|
|
|
|
{
|
|
|
|
return ObjectState(this);
|
|
|
|
};
|
|
|
|
|
|
|
|
//TODO: Return the validity interval of the object as a whole
|
|
|
|
Interval ObjectValidity(TimeValue t)
|
|
|
|
{
|
|
|
|
Interval iv;
|
|
|
|
iv.SetInfinite();
|
|
|
|
iv &= geomValid;
|
|
|
|
//iv &= vcolorValid;
|
|
|
|
iv &= topoValid;
|
|
|
|
iv &= texmapValid;
|
|
|
|
iv &= selectValid;
|
|
|
|
//iv &= gfxdataValid;
|
|
|
|
|
|
|
|
if (!(validBits&chMask[SUBSEL_TYPE_CHAN_NUM])) iv.SetEmpty();
|
|
|
|
if (!(validBits&chMask[DISP_ATTRIB_CHAN_NUM])) iv.SetEmpty();
|
|
|
|
return iv;
|
|
|
|
}
|
|
|
|
|
|
|
|
Interval ChannelValidity(TimeValue t, int nchan)
|
|
|
|
{
|
|
|
|
switch(nchan)
|
|
|
|
{
|
|
|
|
case GEOM_CHAN_NUM: return geomValid; break;
|
|
|
|
case TOPO_CHAN_NUM: return topoValid; break;
|
|
|
|
case TEXMAP_CHAN_NUM: return texmapValid; break;
|
|
|
|
case SELECT_CHAN_NUM: return selectValid; break;
|
|
|
|
default:
|
|
|
|
return((chMask[nchan]&validBits) ? FOREVER: NEVER);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetChannelValidity(int nchan, Interval v)
|
|
|
|
{
|
|
|
|
switch(nchan)
|
|
|
|
{
|
|
|
|
case GEOM_CHAN_NUM: geomValid = v; break;
|
|
|
|
//case VERT_COLOR_CHAN_NUM: vcolorValid = v; break;
|
|
|
|
case TOPO_CHAN_NUM: topoValid = v; break;
|
|
|
|
case TEXMAP_CHAN_NUM: texmapValid = v; break;
|
|
|
|
case SELECT_CHAN_NUM: selectValid = v; break;
|
|
|
|
//case GFX_DATA_CHAN_NUM: gfxdataValid = v; break;
|
|
|
|
default :
|
|
|
|
//if (v.InInterval(0)) validBits|= chMask[nchan];
|
|
|
|
if (!(v==NEVER)) validBits|= chMask[nchan];
|
|
|
|
else validBits &= ~chMask[nchan];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Interval ConvertValidity(TimeValue t)
|
|
|
|
{
|
|
|
|
Interval iv = FOREVER;
|
|
|
|
if (geomValid.InInterval(t)) iv &= geomValid;
|
|
|
|
//if (vcolorValid.InInterval(t)) iv &= vcolorValid;
|
|
|
|
if (topoValid.InInterval(t)) iv &= topoValid;
|
|
|
|
if (texmapValid.InInterval(t)) iv &= texmapValid;
|
|
|
|
if (selectValid.InInterval(t)) iv &= selectValid;
|
|
|
|
return iv;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define copyFlags(dest, source, mask) dest = ((dest&(~mask))|(source&mask))
|
|
|
|
|
|
|
|
void CopyValidity(RPO *fromOb, ChannelMask channels)
|
|
|
|
{
|
|
|
|
if (channels&GEOM_CHANNEL) geomValid = fromOb->geomValid;
|
|
|
|
//if (channels&VERTCOLOR_CHANNEL) vcolorValid = fromOb->vcolorValid;
|
|
|
|
if (channels&TOPO_CHANNEL) topoValid = fromOb->topoValid;
|
|
|
|
if (channels&TEXMAP_CHANNEL) texmapValid = fromOb->texmapValid;
|
|
|
|
if (channels&SELECT_CHANNEL) selectValid = fromOb->selectValid;
|
|
|
|
//if (channels&GFX_DATA_CHANNEL) gfxdataValid = fromOb->gfxdataValid;
|
|
|
|
copyFlags(validBits, fromOb->validBits,channels);
|
|
|
|
}
|
|
|
|
|
|
|
|
void InvalidateChannels(ChannelMask channels);
|
|
|
|
|
|
|
|
// From Animatable
|
|
|
|
void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
|
|
|
|
void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next);
|
|
|
|
|
|
|
|
// From GeomObject
|
|
|
|
Mesh* GetRenderMesh(TimeValue t, INode *inode, View& view, BOOL& needDelete);
|
|
|
|
|
|
|
|
// Loading/Saving
|
|
|
|
IOResult Load(ILoad *iload);
|
|
|
|
IOResult Save(ISave *isave);
|
|
|
|
|
|
|
|
//From Animatable
|
|
|
|
Class_ID ClassID()
|
|
|
|
{
|
|
|
|
if (bBigHack)
|
|
|
|
return Class_ID(PATCHOBJ_CLASS_ID,0);
|
|
|
|
else
|
|
|
|
return RYKOLPATCHOBJ_CLASS_ID;
|
|
|
|
}
|
|
|
|
BOOL IsSubClassOf(Class_ID classID)
|
|
|
|
{
|
|
|
|
return classID == ClassID()
|
|
|
|
? true : PatchObject::IsSubClassOf(classID);
|
|
|
|
}
|
|
|
|
SClass_ID SuperClassID() { return GEOMOBJECT_CLASS_ID; }
|
2016-11-19 20:07:20 +00:00
|
|
|
void GetClassName(TSTR& s) {s.FromUTF8("Rykol Patch Object");}
|
2016-07-25 16:27:53 +00:00
|
|
|
|
|
|
|
RefTargetHandle Clone ( RemapDir &remap );
|
2016-11-19 20:07:52 +00:00
|
|
|
RefResult NotifyRefChanged (const Interval& changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message, BOOL propagate);
|
2016-07-25 16:27:53 +00:00
|
|
|
|
|
|
|
int NumSubs()
|
|
|
|
{
|
|
|
|
return PatchObject::NumSubs ();
|
|
|
|
}
|
|
|
|
//TSTR SubAnimName(int i) { return NULL; }
|
|
|
|
Animatable* SubAnim(int i)
|
|
|
|
{
|
|
|
|
return PatchObject::SubAnim(i);
|
|
|
|
// return pblock;
|
|
|
|
}
|
|
|
|
int NumRefs()
|
|
|
|
{
|
|
|
|
return PatchObject::NumRefs();
|
|
|
|
}
|
|
|
|
RefTargetHandle GetReference(int i)
|
|
|
|
{
|
|
|
|
return PatchObject::GetReference(i);
|
|
|
|
//return pblock;
|
|
|
|
}
|
|
|
|
void SetReference(int i, RefTargetHandle rtarg)
|
|
|
|
{
|
|
|
|
PatchObject::SetReference(i, rtarg);
|
|
|
|
//pblock=(IParamBlock2*)rtarg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*int NumParamBlocks()
|
|
|
|
{
|
|
|
|
//return PatchObject::NumParamBlocks();
|
|
|
|
return 1;
|
|
|
|
} // return number of ParamBlocks in this instance
|
|
|
|
IParamBlock2* GetParamBlock(int i)
|
|
|
|
{
|
|
|
|
//return PatchObject::GetParamBlock(i);
|
|
|
|
return pblock;
|
|
|
|
} // return i'th ParamBlock
|
|
|
|
IParamBlock2* GetParamBlockByID(BlockID id)
|
|
|
|
{
|
|
|
|
return PatchObject::GetParamBlockByID(id);
|
|
|
|
//return (pblock->ID() == id) ? pblock : NULL;
|
|
|
|
} // return id'd ParamBlock*/
|
|
|
|
void DeleteThis() { delete this; }
|
|
|
|
Object *MakeShallowCopy(ChannelMask channels);
|
|
|
|
void ShallowCopy(Object* fromOb, ChannelMask channels);
|
|
|
|
void NewAndCopyChannels(ChannelMask channels);
|
|
|
|
void FreeChannels(ChannelMask channels);
|
|
|
|
|
|
|
|
|
|
|
|
//Constructor/Destructor
|
|
|
|
RPO();
|
|
|
|
RPO(PatchObject& pPO);
|
|
|
|
virtual ~RPO();
|
|
|
|
|
|
|
|
void SetPoint(int i, const Point3& p)
|
|
|
|
{
|
|
|
|
PatchObject::SetPoint(i, p);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if it is a zone.
|
|
|
|
*
|
|
|
|
* skeletonShape must be NULL if no bones.
|
|
|
|
*/
|
|
|
|
static bool isZone (INode& node, TimeValue time);
|
|
|
|
|
|
|
|
#if MAX_RELEASE >= 4000
|
|
|
|
// ace: These functions are needed in max 4
|
|
|
|
// NS: New SubObjType API
|
|
|
|
int NumSubObjTypes() { return 0; }
|
|
|
|
ISubObjType *GetSubObjType(int i) { return NULL; }
|
|
|
|
#endif
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // __RYKOL_PATCH_OBJ_H
|