1 | /**********************************************************************
|
---|
2 | *<
|
---|
3 | FILE: object.h
|
---|
4 |
|
---|
5 | DESCRIPTION: Defines Object Classes
|
---|
6 |
|
---|
7 | CREATED BY: Dan Silva
|
---|
8 |
|
---|
9 | HISTORY: created 9 September 1994
|
---|
10 |
|
---|
11 | *> Copyright (c) 1994, All Rights Reserved.
|
---|
12 | **********************************************************************/
|
---|
13 |
|
---|
14 | #ifndef _OBJECT_
|
---|
15 |
|
---|
16 | #define _OBJECT_
|
---|
17 |
|
---|
18 | #include "inode.h"
|
---|
19 | #include "maxapi.h"
|
---|
20 | #include "plugapi.h"
|
---|
21 | #include "snap.h"
|
---|
22 | #include "genshape.h"
|
---|
23 | #include "nurbslib.h"
|
---|
24 | #include <hitdata.h>
|
---|
25 | #include "imtl.h"
|
---|
26 |
|
---|
27 | typedef short MtlIndex;
|
---|
28 | typedef short TextMapIndex;
|
---|
29 |
|
---|
30 | CoreExport void setHitType(int t);
|
---|
31 | CoreExport int getHitType(void);
|
---|
32 |
|
---|
33 | // Hit test types:
|
---|
34 | #define HITTYPE_POINT 1
|
---|
35 | #define HITTYPE_BOX 2
|
---|
36 | #define HITTYPE_CIRCLE 3
|
---|
37 | #define HITTYPE_SOLID 4
|
---|
38 | #define HITTYPE_FENCE 5
|
---|
39 |
|
---|
40 | // Flags for hit test.
|
---|
41 | #define HIT_SELONLY (1<<0)
|
---|
42 | #define HIT_UNSELONLY (1<<2)
|
---|
43 | #define HIT_ABORTONHIT (1<<3)
|
---|
44 | #define HIT_SELSOLID (1<<4)
|
---|
45 | #define HIT_ANYSOLID (1<<5)
|
---|
46 |
|
---|
47 | // These are filters for hit testing. They also
|
---|
48 | // are combined into the flags parameter.
|
---|
49 | #define HITFLTR_ALL (1<<10)
|
---|
50 | #define HITFLTR_OBJECTS (1<<11)
|
---|
51 | #define HITFLTR_CAMERAS (1<<12)
|
---|
52 | #define HITFLTR_LIGHTS (1<<13)
|
---|
53 | #define HITFLTR_HELPERS (1<<14)
|
---|
54 | #define HITFLTR_WSMOBJECTS (1<<15)
|
---|
55 | #define HITFLTR_SPLINES (1<<16)
|
---|
56 |
|
---|
57 | // Starting at this bit through the 31st bit can be used
|
---|
58 | // by plug-ins for sub-object hit testing
|
---|
59 | #define HITFLAG_STARTUSERBIT 24
|
---|
60 |
|
---|
61 |
|
---|
62 | #define VALID(x) (x)
|
---|
63 |
|
---|
64 | class Modifier;
|
---|
65 | class Object;
|
---|
66 | class NameTab;
|
---|
67 | class Texmap;
|
---|
68 |
|
---|
69 | typedef Object* ObjectHandle;
|
---|
70 |
|
---|
71 | MakeTab(TextMapIndex)
|
---|
72 | typedef TextMapIndexTab TextTab;
|
---|
73 |
|
---|
74 | //---------------------------------------------------------------
|
---|
75 | class IdentityTM: public Matrix3 {
|
---|
76 | public:
|
---|
77 | IdentityTM() { IdentityMatrix(); }
|
---|
78 | };
|
---|
79 |
|
---|
80 | CoreExport extern IdentityTM idTM;
|
---|
81 |
|
---|
82 |
|
---|
83 | //-------------------------------------------------------------
|
---|
84 | // This is passed in to GetRenderMesh to allow objects to do
|
---|
85 | // view dependent rendering.
|
---|
86 | //
|
---|
87 | class View {
|
---|
88 | public:
|
---|
89 | float screenW, screenH; // screen dimensions
|
---|
90 | Matrix3 worldToView;
|
---|
91 | virtual Point2 ViewToScreen(Point3 p)=0;
|
---|
92 | };
|
---|
93 | //-------------------------------------------------------------
|
---|
94 |
|
---|
95 | // Class ID of general deformable object.
|
---|
96 | extern CoreExport Class_ID defObjectClassID;
|
---|
97 |
|
---|
98 | //-------------------------------------------------------------
|
---|
99 |
|
---|
100 | // Class ID of general texture-mappable object.
|
---|
101 | extern CoreExport Class_ID mapObjectClassID;
|
---|
102 |
|
---|
103 | //-------------------------------------------------------------
|
---|
104 | // ChannelMask: bits specific channels in the OSM dataflow.
|
---|
105 |
|
---|
106 | typedef unsigned long ChannelMask;
|
---|
107 |
|
---|
108 | // an array of channel masks for all the channels *within*
|
---|
109 | // the Object.
|
---|
110 | CoreExport extern ChannelMask chMask[];
|
---|
111 |
|
---|
112 | class Object;
|
---|
113 |
|
---|
114 | //-- ObjectState ------------------------------------------------------------
|
---|
115 | // This is what is passed down the pipeline, and ultimately used by the Node
|
---|
116 | // to Display, Hittest, render:
|
---|
117 |
|
---|
118 | // flags bits
|
---|
119 |
|
---|
120 | class ObjectState {
|
---|
121 | ulong flags;
|
---|
122 | Matrix3 *tm;
|
---|
123 | Interval tmvi;
|
---|
124 | int mtl;
|
---|
125 | Interval mtlvi;
|
---|
126 | void AllocTM();
|
---|
127 | public:
|
---|
128 | Object *obj; // object: provides interval with obj->ObjectValidity()
|
---|
129 | CoreExport ObjectState();
|
---|
130 | CoreExport ObjectState(Object *ob);
|
---|
131 | CoreExport ObjectState(const ObjectState& os);
|
---|
132 | CoreExport ~ObjectState();
|
---|
133 | void OSSetFlag(ulong f) { flags |= f; }
|
---|
134 | void OSClearFlag(ulong f) { flags &= ~f; }
|
---|
135 | ulong OSTestFlag(ulong f) const { return flags&f; }
|
---|
136 | CoreExport void OSCopyFlag(ulong f, const ObjectState& fromos);
|
---|
137 | CoreExport ObjectState& operator=(const ObjectState& os);
|
---|
138 | Interval tmValid() const { return tmvi; }
|
---|
139 | Interval mtlValid() const { return mtlvi; }
|
---|
140 | CoreExport Interval Validity(TimeValue t) const;
|
---|
141 | CoreExport int TMIsIdentity() const;
|
---|
142 | CoreExport void SetTM(Matrix3* mat, Interval iv);
|
---|
143 | CoreExport Matrix3* GetTM() const;
|
---|
144 | CoreExport void SetIdentityTM();
|
---|
145 | CoreExport void ApplyTM(Matrix3* mat, Interval iv);
|
---|
146 | CoreExport void CopyTM(const ObjectState &fromos);
|
---|
147 | CoreExport void CopyMtl(const ObjectState &fromos);
|
---|
148 | CoreExport void Invalidate(ChannelMask channels, BOOL checkLock=FALSE);
|
---|
149 | CoreExport void DeleteObj(BOOL checkLock=FALSE);
|
---|
150 | };
|
---|
151 |
|
---|
152 | class INodeTab : public Tab<INode*> {
|
---|
153 | public:
|
---|
154 | void DisposeTemporary() {
|
---|
155 | for (int i=0; i<Count(); i++) (*this)[i]->DisposeTemporary();
|
---|
156 | }
|
---|
157 | };
|
---|
158 |
|
---|
159 | //---------------------------------------------------------------
|
---|
160 | // A reference to a pointer to an instance of this class is passed in
|
---|
161 | // to ModifyObject(). The value of the pointer starts out as NULL, but
|
---|
162 | // the modifier can set it to point at an actual instance of a derived
|
---|
163 | // class. When the mod app is deleted, if the pointer is not NULL, the
|
---|
164 | // LocalModData will be deleted - the virtual destructor alows this to work.
|
---|
165 |
|
---|
166 | class LocalModData {
|
---|
167 | public:
|
---|
168 | virtual ~LocalModData() {}
|
---|
169 | virtual LocalModData *Clone()=0;
|
---|
170 | };
|
---|
171 |
|
---|
172 | class ModContext {
|
---|
173 | public:
|
---|
174 | Matrix3 *tm;
|
---|
175 | Box3 *box;
|
---|
176 | LocalModData *localData;
|
---|
177 |
|
---|
178 | CoreExport ~ModContext();
|
---|
179 | CoreExport ModContext();
|
---|
180 | CoreExport ModContext(const ModContext& mc);
|
---|
181 | CoreExport ModContext(Matrix3 *tm, Box3 *box, LocalModData *localData);
|
---|
182 | };
|
---|
183 |
|
---|
184 | class ModContextList : public Tab<ModContext*> {};
|
---|
185 |
|
---|
186 |
|
---|
187 | class HitRecord;
|
---|
188 |
|
---|
189 |
|
---|
190 |
|
---|
191 |
|
---|
192 |
|
---|
193 | // Flags passed to Display()
|
---|
194 | #define USE_DAMAGE_RECT (1<<0)
|
---|
195 | #define DISP_SHOWSUBOBJECT (1<<1)
|
---|
196 |
|
---|
197 | // The base class of Geometric objects, Lights, Cameras, Modifiers,
|
---|
198 | // Deformation objects--
|
---|
199 | // --anything with a 3D representation in the UI scene.
|
---|
200 |
|
---|
201 | class IParamArray;
|
---|
202 |
|
---|
203 | class BaseObject: public ReferenceTarget {
|
---|
204 | public:
|
---|
205 | CoreExport void* GetInterface(ULONG id);
|
---|
206 |
|
---|
207 | virtual int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt){return 0;};
|
---|
208 | virtual void SetExtendedDisplay(int flags) {} // for setting mode-dependent display attributes
|
---|
209 | virtual int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags) { return 0; }; // quick render in viewport, using current TM.
|
---|
210 | virtual void Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt) {} // Check for snap, updating SnapInfo
|
---|
211 | virtual void GetWorldBoundBox(TimeValue t, INode * inode, ViewExp* vp, Box3& box ){}; // Box in world coords.
|
---|
212 | virtual void GetLocalBoundBox(TimeValue t, INode* inode, ViewExp* vp, Box3& box ){}; // box in objects local coords
|
---|
213 | virtual CreateMouseCallBack* GetCreateMouseCallBack()=0;
|
---|
214 |
|
---|
215 | // This is the name that will appear in the history browser.
|
---|
216 | virtual TCHAR *GetObjectName() { return _T("Object"); }
|
---|
217 |
|
---|
218 | // Sends the REFMSG_IS_OK_TO_CHANGE_TOPOLOGY off to see if any
|
---|
219 | // modifiers or objects down the pipeline depend on topology.
|
---|
220 | // modName will be set to the dependent modifier's name if there is one.
|
---|
221 | CoreExport virtual BOOL OKToChangeTopology(TSTR &modName);
|
---|
222 |
|
---|
223 | // Return true if this object(or modifier) is cabable of changing
|
---|
224 | //topology when it's parameters are being edited.
|
---|
225 | virtual BOOL ChangeTopology() {return TRUE;}
|
---|
226 |
|
---|
227 | virtual void ForceNotify(Interval& i)
|
---|
228 | {NotifyDependents(i, PART_ALL,REFMSG_CHANGE);}
|
---|
229 |
|
---|
230 | // If an object or modifier wishes it can make its parameter block
|
---|
231 | // available for other plug-ins to access. The system itself doesn't
|
---|
232 | // actually call this method -- this method is optional.
|
---|
233 | virtual IParamArray *GetParamBlock() {return NULL;}
|
---|
234 |
|
---|
235 | // If a plug-in make its parameter block available then it will
|
---|
236 | // need to provide #defines for indices into the parameter block.
|
---|
237 | // These defines should probably not be directly used with the
|
---|
238 | // parameter block but instead converted by this function that the
|
---|
239 | // plug-in implements. This way if a parameter moves around in a
|
---|
240 | // future version of the plug-in the #define can be remapped.
|
---|
241 | // -1 indicates an invalid parameter id
|
---|
242 | virtual int GetParamBlockIndex(int id) {return -1;}
|
---|
243 |
|
---|
244 |
|
---|
245 | ///////////////////////////////////////////////////////////////////////////
|
---|
246 | ///////////////////////////////////////////////////////////////////////////
|
---|
247 | //
|
---|
248 | // The following methods are for sub-object selection. If the
|
---|
249 | // derived class is NOT a modifier, the modContext pointer passed
|
---|
250 | // to some of the methods will be NULL.
|
---|
251 | //
|
---|
252 |
|
---|
253 | // Affine transform methods
|
---|
254 | virtual void Move( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE ){}
|
---|
255 | virtual void Rotate( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Quat& val, BOOL localOrigin=FALSE ){}
|
---|
256 | virtual void Scale( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE ){}
|
---|
257 |
|
---|
258 | // The following is called before the first Move(), Rotate() or Scale() call and
|
---|
259 | // before a hold is in effect
|
---|
260 | virtual void TransformStart(TimeValue t) {}
|
---|
261 |
|
---|
262 | // The following is called before the first Move(), Rotate() or Scale() call and
|
---|
263 | // after a hold is in effect
|
---|
264 | virtual void TransformHoldingStart(TimeValue t) {}
|
---|
265 |
|
---|
266 | // The following is called after the user has completed the Move, Rotate or Scale operation and
|
---|
267 | // before the undo object has been accepted.
|
---|
268 | virtual void TransformHoldingFinish(TimeValue t) {}
|
---|
269 |
|
---|
270 | // The following is called after the user has completed the Move, Rotate or Scale operation and
|
---|
271 | // after the undo object has been accepted.
|
---|
272 | virtual void TransformFinish(TimeValue t) {}
|
---|
273 |
|
---|
274 | // The following is called when the transform operation is cancelled by a right-click and
|
---|
275 | // the undo has been cancelled.
|
---|
276 | virtual void TransformCancel(TimeValue t) {}
|
---|
277 |
|
---|
278 | virtual int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc) { return 0; }
|
---|
279 | virtual int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags, ModContext* mc) { return 0; }; // quick render in viewport, using current TM.
|
---|
280 | virtual void GetWorldBoundBox(TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc) {}
|
---|
281 |
|
---|
282 | virtual void CloneSelSubComponents(TimeValue t) {}
|
---|
283 | virtual void AcceptCloneSelSubComponents(TimeValue t) {}
|
---|
284 |
|
---|
285 | // Changes the selection state of the component identified by the
|
---|
286 | // hit record.
|
---|
287 | virtual void SelectSubComponent(
|
---|
288 | HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert=FALSE) {}
|
---|
289 |
|
---|
290 | // Clears the selection for the given sub-object type.
|
---|
291 | virtual void ClearSelection(int selLevel) {}
|
---|
292 | virtual void SelectAll(int selLevel) {}
|
---|
293 | virtual void InvertSelection(int selLevel) {}
|
---|
294 |
|
---|
295 | // Returns the index of the subobject entity identified by hitRec.
|
---|
296 | virtual int SubObjectIndex(HitRecord *hitRec) {return 0;}
|
---|
297 |
|
---|
298 | // This notifies an object being edited that the current sub object
|
---|
299 | // selection level has changed. level==0 indicates object level selection.
|
---|
300 | // level==1 or greater refer to the types registered by the object in the
|
---|
301 | // order they appeared in the list when registered.
|
---|
302 | // If level >= 1, the object should specify sub-object xform modes in the
|
---|
303 | // modes structure (defined in cmdmode.h).
|
---|
304 | virtual void ActivateSubobjSel(int level, XFormModes& modes ) {}
|
---|
305 |
|
---|
306 | // An object that supports sub-object selection can choose to
|
---|
307 | // support named sub object selection sets. Methods in the the
|
---|
308 | // interface passed to objects allow them to add items to the
|
---|
309 | // sub-object selection set drop down.
|
---|
310 | // The following methods are called when the user picks items
|
---|
311 | // from the list.
|
---|
312 | virtual BOOL SupportsNamedSubSels() {return FALSE;}
|
---|
313 | virtual void ActivateSubSelSet(TSTR &setName) {}
|
---|
314 | virtual void NewSetFromCurSel(TSTR &setName) {}
|
---|
315 | virtual void RemoveSubSelSet(TSTR &setName) {}
|
---|
316 |
|
---|
317 | // New way of dealing with sub object coordinate systems.
|
---|
318 | // Plug-in enumerates its centers or TMs and calls the callback once for each.
|
---|
319 | // NOTE:cb->Center() should be called the same number of times and in the
|
---|
320 | // same order as cb->TM()
|
---|
321 | // NOTE: The SubObjAxisCallback class is defined in animatable and used in both the
|
---|
322 | // controller version and this version of GetSubObjectCenters() and GetSubObjectTMs()
|
---|
323 | virtual void GetSubObjectCenters(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc) {}
|
---|
324 | virtual void GetSubObjectTMs(SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc) {}
|
---|
325 |
|
---|
326 | //
|
---|
327 | //
|
---|
328 | ///////////////////////////////////////////////////////////////////////////
|
---|
329 | ///////////////////////////////////////////////////////////////////////////
|
---|
330 |
|
---|
331 | private:
|
---|
332 | };
|
---|
333 |
|
---|
334 | //-------------------------------------------------------------
|
---|
335 | // Callback object used by Modifiers to deform "Deformable" objects
|
---|
336 | class Deformer {
|
---|
337 | public:
|
---|
338 | virtual Point3 Map(int i, Point3 p) = 0;
|
---|
339 | void ApplyToTM(Matrix3* tm);
|
---|
340 | };
|
---|
341 |
|
---|
342 | // Mapping types passed to ApplyUVWMap()
|
---|
343 | #define MAP_PLANAR 0
|
---|
344 | #define MAP_CYLINDRICAL 1
|
---|
345 | #define MAP_SPHERICAL 2
|
---|
346 | #define MAP_BALL 3
|
---|
347 | #define MAP_BOX 4
|
---|
348 |
|
---|
349 | /*-------------------------------------------------------------------
|
---|
350 | Object is the class of all objects that can be pointed to by a node:
|
---|
351 | It INcludes Lights,Cameras, Geometric objects, derived objects,
|
---|
352 | and deformation Objects (e.g. FFD lattices)
|
---|
353 | It EXcludes Modifiers
|
---|
354 | ---------------------------------------------------------------------*/
|
---|
355 | #define OBJECT_LOCKED 0x8000000
|
---|
356 |
|
---|
357 | class ShapeObject;
|
---|
358 |
|
---|
359 | class Object: public BaseObject {
|
---|
360 | ulong locked; // lock flags for each channel + object locked flag
|
---|
361 | Interval noEvalInterval; // used in ReducingCaches
|
---|
362 | public:
|
---|
363 | Object() { locked = OBJECT_LOCKED; noEvalInterval = FOREVER; }
|
---|
364 |
|
---|
365 | virtual int IsRenderable()=0; // is this a renderable object?
|
---|
366 | virtual void InitNodeName(TSTR& s)=0;
|
---|
367 | virtual int UsesWireColor() { return TRUE; } // TRUE if the object color is used for display
|
---|
368 | virtual int DoOwnSelectHilite() { return 0; }
|
---|
369 | // validity interval of Object as a whole at current time
|
---|
370 | virtual Interval ObjectValidity(TimeValue t) { return FOREVER; }
|
---|
371 |
|
---|
372 | // This used to be in GeomObject but I realized that other types of objects may
|
---|
373 | // want this (mainly to participate in normal align) such as grid helper objects.
|
---|
374 | virtual int IntersectRay(TimeValue t, Ray& r, float& at, Point3& norm) {return FALSE;}
|
---|
375 |
|
---|
376 | // locking of object as whole. defaults to NOT modifiable.
|
---|
377 | void LockObject() { locked |= OBJECT_LOCKED; }
|
---|
378 | void UnlockObject() { locked &= ~OBJECT_LOCKED; }
|
---|
379 | int IsObjectLocked() { return locked&OBJECT_LOCKED; }
|
---|
380 |
|
---|
381 | // the validity intervals are now in the object.
|
---|
382 | virtual ObjectState Eval(TimeValue t)=0;
|
---|
383 |
|
---|
384 | // Access the lock flags for th specified channels
|
---|
385 | void LockChannels(ChannelMask channels) { locked |= channels; }
|
---|
386 | void UnlockChannels(ChannelMask channels) { locked &= ~channels; }
|
---|
387 | ChannelMask GetChannelLocks() { return locked; }
|
---|
388 | void SetChannelLocks(ChannelMask channels) { locked = channels; }
|
---|
389 | ChannelMask GetChannelLocks(ChannelMask m) { return locked; }
|
---|
390 |
|
---|
391 | // Can this object have channels cached?
|
---|
392 | // Particle objects flow up the pipline without making shallow copies of themselves and therefore cannot be cached
|
---|
393 | virtual BOOL CanCacheObject() {return TRUE;}
|
---|
394 |
|
---|
395 | // This is called by a node when the node's world space state has
|
---|
396 | // become invalid. Normally an object does not (and should not) be
|
---|
397 | // concerned with this, but in certain cases (particle systems) an
|
---|
398 | // object is effectively a world space object an needs to be notified.
|
---|
399 | virtual void WSStateInvalidate() {}
|
---|
400 |
|
---|
401 | // Identifies the object as a world space object. World space
|
---|
402 | // objects (particles for example) can not be instanced because
|
---|
403 | // they exist in world space not object space.
|
---|
404 | virtual BOOL IsWorldSpaceObject() {return FALSE;}
|
---|
405 |
|
---|
406 | // copy specified flags from obj
|
---|
407 | CoreExport void CopyChannelLocks(Object *obj, ChannelMask needChannels);
|
---|
408 |
|
---|
409 | // access the current validity interval for the nth channel
|
---|
410 | CoreExport virtual Interval ChannelValidity(TimeValue t, int nchan);
|
---|
411 | virtual void SetChannelValidity(int nchan, Interval v) { }
|
---|
412 | CoreExport void UpdateValidity(int nchan, Interval v); // AND in interval v to channel validity
|
---|
413 |
|
---|
414 | // invalidate the specified channels
|
---|
415 | virtual void InvalidateChannels(ChannelMask channels) { }
|
---|
416 |
|
---|
417 | //
|
---|
418 | // does this object implement the generic Deformable Object procs?
|
---|
419 | //
|
---|
420 | virtual int IsDeformable() { return 0; }
|
---|
421 |
|
---|
422 | // DeformableObject procs: only need be implemented
|
---|
423 | // IsDeformable() returns TRUE.
|
---|
424 | virtual int NumPoints(){ return 0;}
|
---|
425 | virtual Point3 GetPoint(int i) { return Point3(0,0,0); }
|
---|
426 | virtual void SetPoint(int i, const Point3& p) {}
|
---|
427 |
|
---|
428 | // informs the object that its points have been deformed,
|
---|
429 | // so it can invalidate its cache.
|
---|
430 | virtual void PointsWereChanged(){}
|
---|
431 |
|
---|
432 | // deform the object with a deformer.
|
---|
433 | CoreExport virtual void Deform(Deformer *defProc, int useSel=0);
|
---|
434 |
|
---|
435 | // box in objects local coords or optional space defined by tm
|
---|
436 | // If useSel is true, the bounding box of selected sub-elements will be taken.
|
---|
437 | CoreExport virtual void GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm=NULL, BOOL useSel=FALSE );
|
---|
438 |
|
---|
439 | //
|
---|
440 | // does this object implement the generic Mappable Object procs?
|
---|
441 | //
|
---|
442 | virtual int IsMappable() { return 0; }
|
---|
443 |
|
---|
444 | // This does the texture map application -- Only need to implement if
|
---|
445 | // IsMappable returns TRUE
|
---|
446 | virtual void ApplyUVWMap(int type,
|
---|
447 | float utile, float vtile, float wtile,
|
---|
448 | int uflip, int vflip, int wflip, int cap,
|
---|
449 | const Matrix3 &tm) {}
|
---|
450 |
|
---|
451 | // Objects need to be able convert themselves
|
---|
452 | // to TriObjects. Most modifiers will ask for
|
---|
453 | // Deformable Objects, and triobjects will suffice.
|
---|
454 |
|
---|
455 | CoreExport virtual int CanConvertToType(Class_ID obtype);
|
---|
456 | CoreExport virtual Object* ConvertToType(TimeValue t, Class_ID obtype);
|
---|
457 |
|
---|
458 | // return the current sub-selection state
|
---|
459 | virtual DWORD GetSubselState() {return 0;}
|
---|
460 | virtual void SetSubSelState(DWORD s) {}
|
---|
461 |
|
---|
462 | // If the requested channels are locked, replace their data
|
---|
463 | // with a copy/ and unlock them, otherwise leave them alone
|
---|
464 | CoreExport void ReadyChannelsForMod(ChannelMask channels);
|
---|
465 |
|
---|
466 | // Virtual methods to be implemented by plug-in object:-----
|
---|
467 |
|
---|
468 | // Makes a copy of its "shell" and shallow copies only the
|
---|
469 | // specified channels. Also copies the validity intervals of
|
---|
470 | // the copied channels, and sets Invalidates the other intervals.
|
---|
471 | virtual Object *MakeShallowCopy(ChannelMask channels) { return NULL; }
|
---|
472 |
|
---|
473 | // Shallow-copies the specified channels from the fromOb to this.
|
---|
474 | // Also copies the validity intervals.
|
---|
475 | virtual void ShallowCopy(Object* fromOb, ChannelMask channels) {}
|
---|
476 |
|
---|
477 | // This replaces locked channels with newly allocated copies.
|
---|
478 | // It will only be called if the channel is locked.
|
---|
479 | virtual void NewAndCopyChannels(ChannelMask channels) {}
|
---|
480 |
|
---|
481 | // Free the specified channels
|
---|
482 | virtual void FreeChannels(ChannelMask channels) {}
|
---|
483 |
|
---|
484 | Interval GetNoEvalInterval() { return noEvalInterval; }
|
---|
485 | void SetNoEvalInterval(Interval iv) {noEvalInterval = iv; }
|
---|
486 |
|
---|
487 | // Give the object chance to reduce its caches,
|
---|
488 | // depending on the noEvalInterval.
|
---|
489 | CoreExport virtual void ReduceCaches(TimeValue t);
|
---|
490 |
|
---|
491 | // Is this object a construction object:
|
---|
492 | virtual int IsConstObject() { return 0; }
|
---|
493 |
|
---|
494 | // Retreives sub-object branches from an object that supports branching.
|
---|
495 | // Certain objects combine a series of input objects (pipelines) into
|
---|
496 | // a single object. These objects act as a multiplexor allowing the
|
---|
497 | // user to decide which branch(s) they want to see the history for.
|
---|
498 | //
|
---|
499 | // It is up to the object how they want to let the user choose. The object
|
---|
500 | // may use sub object selection to allow the user to pick a set of
|
---|
501 | // objects for which the common history will be displayed.
|
---|
502 | //
|
---|
503 | // When the history changes for any reason, the object should send
|
---|
504 | // a notification (REFMSG_BRANCHED_HISTORY_CHANGED) via NotifyDependents.
|
---|
505 | //
|
---|
506 | virtual int NumPipeBranches() {return 0;}
|
---|
507 | virtual Object *GetPipeBranch(int i) {return NULL;}
|
---|
508 |
|
---|
509 | // When an object has sub-object branches, it is likely that the
|
---|
510 | // sub-objects are transformed relative to the object. This method
|
---|
511 | // gives the object a chance to modify the node's transformation so
|
---|
512 | // that operations (like edit modifiers) will work correctly when
|
---|
513 | // editing the history of the sub object branch.
|
---|
514 | virtual INode *GetBranchINode(TimeValue t,INode *node,int i) {return node;}
|
---|
515 |
|
---|
516 | // Shape viewports can reference shapes contained within objects, so we
|
---|
517 | // need to be able to access shapes within an object. The following methods
|
---|
518 | // provide this access
|
---|
519 | virtual int NumberOfContainedShapes() { return -1; } // NOT a container!
|
---|
520 | virtual ShapeObject *GetContainedShape(TimeValue t, int index) { return NULL; }
|
---|
521 | virtual void GetContainedShapeMatrix(TimeValue t, int index, Matrix3 &mat) {}
|
---|
522 | virtual BitArray ContainedShapeSelectionArray() { return BitArray(); }
|
---|
523 |
|
---|
524 | // For debugging only. TriObject inplements this method by making sure
|
---|
525 | // its face's vert indices are all valid.
|
---|
526 | virtual BOOL CheckObjectIntegrity() {return TRUE;}
|
---|
527 | };
|
---|
528 |
|
---|
529 |
|
---|
530 | /*-------------------------------------------------------------------
|
---|
531 | CameraObject:
|
---|
532 | ---------------------------------------------------------------------*/
|
---|
533 |
|
---|
534 | #define CAM_HITHER_CLIP 1
|
---|
535 | #define CAM_YON_CLIP 2
|
---|
536 |
|
---|
537 | #define ENV_NEAR_RANGE 0
|
---|
538 | #define ENV_FAR_RANGE 1
|
---|
539 |
|
---|
540 | struct CameraState {
|
---|
541 | float fov;
|
---|
542 | float tdist; // target distance for free cameras
|
---|
543 | BOOL horzLine; // horizon line display state
|
---|
544 | int manualClip;
|
---|
545 | float hither;
|
---|
546 | float yon;
|
---|
547 | float nearRange;
|
---|
548 | float farRange;
|
---|
549 | };
|
---|
550 |
|
---|
551 | class CameraObject: public Object {
|
---|
552 | public:
|
---|
553 | SClass_ID SuperClassID() { return CAMERA_CLASS_ID; }
|
---|
554 | int IsRenderable() { return(0);}
|
---|
555 | virtual void InitNodeName(TSTR& s) { s = _T("Camera"); }
|
---|
556 | virtual int UsesWireColor() { return FALSE; } // TRUE if the object color is used for display
|
---|
557 |
|
---|
558 | // Method specific to cameras:
|
---|
559 | virtual RefResult EvalCameraState(TimeValue time, Interval& valid, CameraState* cs)=0;
|
---|
560 | virtual void SetFOV(TimeValue time, float f)=0;
|
---|
561 | virtual float GetFOV(TimeValue t, Interval& valid = Interval(0,0))=0;
|
---|
562 | virtual void SetTDist(TimeValue time, float f)=0;
|
---|
563 | virtual float GetTDist(TimeValue t, Interval& valid = Interval(0,0))=0;
|
---|
564 | virtual int GetManualClip()=0;
|
---|
565 | virtual void SetManualClip(int onOff)=0;
|
---|
566 | virtual float GetClipDist(TimeValue t, int which, Interval &valid=Interval(0,0))=0;
|
---|
567 | virtual void SetClipDist(TimeValue t, int which, float val)=0;
|
---|
568 | virtual void SetEnvRange(TimeValue time, int which, float f)=0;
|
---|
569 | virtual float GetEnvRange(TimeValue t, int which, Interval& valid = Interval(0,0))=0;
|
---|
570 | virtual void SetEnvDisplay(BOOL b, int notify=TRUE)=0;
|
---|
571 | virtual BOOL GetEnvDisplay(void)=0;
|
---|
572 | };
|
---|
573 |
|
---|
574 |
|
---|
575 | /*-------------------------------------------------------------------
|
---|
576 | LightObject:
|
---|
577 | ---------------------------------------------------------------------*/
|
---|
578 |
|
---|
579 | #define LIGHT_ATTEN_START 0
|
---|
580 | #define LIGHT_ATTEN_END 1
|
---|
581 |
|
---|
582 | struct LightState {
|
---|
583 | LightType type;
|
---|
584 | Matrix3 tm;
|
---|
585 | Color color;
|
---|
586 | float intens; // multiplier value
|
---|
587 | float hotsize;
|
---|
588 | float fallsize;
|
---|
589 | int useAtten;
|
---|
590 | float attenStart;
|
---|
591 | float attenEnd;
|
---|
592 | int shape;
|
---|
593 | float aspect;
|
---|
594 | BOOL overshoot;
|
---|
595 | BOOL shadow;
|
---|
596 | BOOL on; // light is on
|
---|
597 | };
|
---|
598 |
|
---|
599 | class LightDesc;
|
---|
600 | class RendContext;
|
---|
601 |
|
---|
602 |
|
---|
603 | // This is a callback class that can be given to a ObjLightDesc
|
---|
604 | // to have a ray traced through the light volume.
|
---|
605 | class LightRayTraversal {
|
---|
606 | public:
|
---|
607 | // This is called for every step (return FALSE to halt the integration).
|
---|
608 | // t0 and t1 define the segment in terms of the given ray.
|
---|
609 | // illum is the light intensity over the entire segment. It can be
|
---|
610 | // assumed that the light intensty is constant for the segment.
|
---|
611 | virtual BOOL Step(float t0, float t1, Color illum)=0;
|
---|
612 | };
|
---|
613 |
|
---|
614 | // Flags passed to TraverseVolume
|
---|
615 | #define TRAVERSE_LOWFILTSHADOWS (1<<0)
|
---|
616 | #define TRAVERSE_HIFILTSHADOWS (1<<1)
|
---|
617 |
|
---|
618 | // A light must be able to create one of these to give to the renderer.
|
---|
619 | // The Illuminate() method (inherited from LightDesc) is called by the renderer
|
---|
620 | // to illuminate a surface point.
|
---|
621 | class ObjLightDesc : public LightDesc {
|
---|
622 | public:
|
---|
623 | // This data will be set up by the default implementation of Update()
|
---|
624 | LightState ls;
|
---|
625 | INode *inode;
|
---|
626 | BOOL uniformScale; // for optimizing
|
---|
627 | Point3 lightPos;
|
---|
628 | Matrix3 lightToWorld;
|
---|
629 | Matrix3 worldToLight;
|
---|
630 | Matrix3 lightToCam; // updated in UpdateViewDepParams
|
---|
631 | Matrix3 camToLight; // updated in UpdateViewDepParams
|
---|
632 |
|
---|
633 | CoreExport ObjLightDesc(INode *n);
|
---|
634 | CoreExport virtual ~ObjLightDesc();
|
---|
635 |
|
---|
636 | virtual NameTab* GetExclList() { return NULL; }
|
---|
637 |
|
---|
638 | // update light state that depends on position of objects&lights in world.
|
---|
639 | CoreExport virtual int Update(TimeValue t, const RendContext &rc, BOOL shadows);
|
---|
640 |
|
---|
641 | // update light state that depends on view matrix.
|
---|
642 | CoreExport virtual int UpdateViewDepParams(const Matrix3& worldToCam);
|
---|
643 |
|
---|
644 | // This function traverses a ray through the light volume.
|
---|
645 | // 'ray' defines the parameter line that will be traversed.
|
---|
646 | // 'minStep' is the smallest step size that caller requires, Note that
|
---|
647 | // the callback may be called in smaller steps if they light needs to
|
---|
648 | // take smaller steps to avoid under sampling the volume.
|
---|
649 | // 'tStop' is the point at which the traversal will stop (ray.p+tStop*ray.dir).
|
---|
650 | // Note that the traversal can terminate earlier if the callback returns FALSE.
|
---|
651 | // 'proc' is the callback object.
|
---|
652 | //
|
---|
653 | // attenStart/End specify a percent of the light attenuation distances
|
---|
654 | // that should be used for lighting durring the traversal.
|
---|
655 | //
|
---|
656 | // The shade context passed in should only be used for state (like are
|
---|
657 | // shadows globaly disabled). The position, normal, etc. serve no purpose.
|
---|
658 | virtual void TraverseVolume(
|
---|
659 | ShadeContext& sc,
|
---|
660 | const Ray &ray, int samples, float tStop,
|
---|
661 | float attenStart, float attenEnd,
|
---|
662 | DWORD flags,
|
---|
663 | LightRayTraversal *proc) {}
|
---|
664 | };
|
---|
665 |
|
---|
666 | // Values returned from GetShadowMethod()
|
---|
667 | #define LIGHTSHADOW_NONE 0
|
---|
668 | #define LIGHTSHADOW_MAPPED 1
|
---|
669 | #define LIGHTSHADOW_RAYTRACED 2
|
---|
670 |
|
---|
671 |
|
---|
672 | class LightObject: public Object {
|
---|
673 | public:
|
---|
674 | SClass_ID SuperClassID() { return LIGHT_CLASS_ID; }
|
---|
675 | int IsRenderable() { return(0);}
|
---|
676 | virtual void InitNodeName(TSTR& s) { s = _T("Light"); }
|
---|
677 |
|
---|
678 | // Methods specific to Lights:
|
---|
679 | virtual RefResult EvalLightState(TimeValue time, Interval& valid, LightState *ls)=0;
|
---|
680 | virtual ObjLightDesc *CreateLightDesc(INode *n) {return NULL;}
|
---|
681 | virtual void SetUseLight(int onOff)=0;
|
---|
682 | virtual BOOL GetUseLight(void)=0;
|
---|
683 | virtual void SetHotspot(TimeValue time, float f)=0;
|
---|
684 | virtual float GetHotspot(TimeValue t, Interval& valid = Interval(0,0))=0;
|
---|
685 | virtual void SetFallsize(TimeValue time, float f)=0;
|
---|
686 | virtual float GetFallsize(TimeValue t, Interval& valid = Interval(0,0))=0;
|
---|
687 | virtual void SetAtten(TimeValue time, int which, float f)=0;
|
---|
688 | virtual float GetAtten(TimeValue t, int which, Interval& valid = Interval(0,0))=0;
|
---|
689 | virtual void SetTDist(TimeValue time, float f)=0;
|
---|
690 | virtual float GetTDist(TimeValue t, Interval& valid = Interval(0,0))=0;
|
---|
691 | virtual void SetConeDisplay(int s, int notify=TRUE)=0;
|
---|
692 | virtual BOOL GetConeDisplay(void)=0;
|
---|
693 | virtual int GetShadowMethod() {return LIGHTSHADOW_NONE;}
|
---|
694 | virtual void SetRGBColor(TimeValue t, Point3& rgb) {}
|
---|
695 | virtual Point3 GetRGBColor(TimeValue t, Interval &valid = Interval(0,0)) {return Point3(0,0,0);}
|
---|
696 | virtual void SetIntensity(TimeValue time, float f) {}
|
---|
697 | virtual float GetIntensity(TimeValue t, Interval& valid = Interval(0,0)) {return 0.0f;}
|
---|
698 | virtual void SetAspect(TimeValue t, float f) {}
|
---|
699 | virtual float GetAspect(TimeValue t, Interval& valid = Interval(0,0)) {return 0.0f;}
|
---|
700 | virtual void SetUseAtten(int s) {}
|
---|
701 | virtual BOOL GetUseAtten(void) {return FALSE;}
|
---|
702 | virtual void SetAttenDisplay(int s) {}
|
---|
703 | virtual BOOL GetAttenDisplay(void) {return FALSE;}
|
---|
704 | virtual void Enable(int enab) {}
|
---|
705 | virtual void SetMapBias(TimeValue t, float f) {}
|
---|
706 | virtual float GetMapBias(TimeValue t, Interval& valid = Interval(0,0)) {return 0.0f;}
|
---|
707 | virtual void SetMapRange(TimeValue t, float f) {}
|
---|
708 | virtual float GetMapRange(TimeValue t, Interval& valid = Interval(0,0)) {return 0.0f;}
|
---|
709 | virtual void SetMapSize(TimeValue t, int f) {}
|
---|
710 | virtual int GetMapSize(TimeValue t, Interval& valid = Interval(0,0)) {return 0;}
|
---|
711 | virtual void SetRayBias(TimeValue t, float f) {}
|
---|
712 | virtual float GetRayBias(TimeValue t, Interval& valid = Interval(0,0)) {return 0.0f;}
|
---|
713 | virtual int GetUseGlobal() {return 0;}
|
---|
714 | virtual void SetUseGlobal(int a) {}
|
---|
715 | virtual int GetShadow() {return 0;}
|
---|
716 | virtual void SetShadow(int a) {}
|
---|
717 | virtual int GetShadowType() {return 0;}
|
---|
718 | virtual void SetShadowType(int a) {}
|
---|
719 | virtual int GetAbsMapBias() {return 0;}
|
---|
720 | virtual void SetAbsMapBias(int a) {}
|
---|
721 | virtual int GetOvershoot() {return 0;}
|
---|
722 | virtual void SetOvershoot(int a) {}
|
---|
723 | virtual int GetProjector() {return 0;}
|
---|
724 | virtual void SetProjector(int a) {}
|
---|
725 | virtual NameTab* GetExclList() {return NULL;}
|
---|
726 | virtual BOOL Include() {return FALSE;}
|
---|
727 | virtual Texmap* GetProjMap() {return NULL;}
|
---|
728 | virtual void SetProjMap(Texmap* pmap) {}
|
---|
729 | };
|
---|
730 |
|
---|
731 | /*-------------------------------------------------------------------
|
---|
732 | HelperObject:
|
---|
733 | ---------------------------------------------------------------------*/
|
---|
734 |
|
---|
735 | class HelperObject: public Object {
|
---|
736 | public:
|
---|
737 | SClass_ID SuperClassID() { return HELPER_CLASS_ID; }
|
---|
738 | int IsRenderable() { return(0); }
|
---|
739 | virtual void InitNodeName(TSTR& s) { s = _T("Helper"); }
|
---|
740 | virtual int UsesWireColor() { return FALSE; } // TRUE if the object color is used for display
|
---|
741 |
|
---|
742 | };
|
---|
743 |
|
---|
744 | /*-------------------------------------------------------------------
|
---|
745 | ConstObject:
|
---|
746 | ---------------------------------------------------------------------*/
|
---|
747 |
|
---|
748 | class ConstObject: public HelperObject {
|
---|
749 | private:
|
---|
750 | public:
|
---|
751 |
|
---|
752 | // Override this function in HelperObject!
|
---|
753 | int IsConstObject() { return 1; }
|
---|
754 |
|
---|
755 | // Methods specific to construction grids:
|
---|
756 | virtual void GetConstructionTM( TimeValue t, INode* inode, ViewExp *vpt, Matrix3 &tm ) = 0; // Get the transform for this view
|
---|
757 | virtual Point3& GetSnaps( TimeValue t ) = 0; // Get snap values
|
---|
758 | };
|
---|
759 |
|
---|
760 | /*-------------------------------------------------------------------
|
---|
761 | GeomObject: these are the Renderable objects.
|
---|
762 | ---------------------------------------------------------------------*/
|
---|
763 |
|
---|
764 | class GeomObject: public Object {
|
---|
765 | public:
|
---|
766 | virtual void InitNodeName(TSTR& s) { s = _T("Object"); }
|
---|
767 | SClass_ID SuperClassID() { return GEOMOBJECT_CLASS_ID; }
|
---|
768 |
|
---|
769 | virtual int IsRenderable() { return(1); }
|
---|
770 |
|
---|
771 | // If an object creates different meshes depending on the
|
---|
772 | // particular instance (view-dependent) it should return 1.
|
---|
773 | virtual int IsInstanceDependent() { return 0; }
|
---|
774 |
|
---|
775 | // GetRenderMesh should be implemented by all renderable GeomObjects.
|
---|
776 | // set needDelete to TRUE if the render should delete the mesh, FALSE otherwise
|
---|
777 | // Primitives that already have a mesh cached can just return a pointer
|
---|
778 | // to it (and set needDelete = FALSE).
|
---|
779 | CoreExport virtual Mesh* GetRenderMesh(TimeValue t, INode *inode, View& view, BOOL& needDelete);
|
---|
780 |
|
---|
781 | // If this returns NULL, then GetRenderMesh will be called
|
---|
782 | CoreExport virtual PatchMesh* GetRenderPatchMesh(TimeValue t, INode *inode, View& view, BOOL& needDelete);
|
---|
783 |
|
---|
784 | // If this returns NULL, then GetRenderPatchMesh will be called
|
---|
785 | CoreExport virtual NurbsMesh* GetRenderNurbsMesh(TimeValue t, INode *inode, View& view, BOOL& needDelete);
|
---|
786 |
|
---|
787 | private:
|
---|
788 | };
|
---|
789 |
|
---|
790 |
|
---|
791 | //-- Particle Systems ---------------------------------------------------
|
---|
792 |
|
---|
793 | // A force field can be applied to a particle system by a SpaceWarp.
|
---|
794 | // The force field provides a function of position in space, velocity
|
---|
795 | // and time that gives a force.
|
---|
796 | // The force is then used to compute an acceleration on a particle
|
---|
797 | // which modifies its velocity. Typically, particles are assumed to
|
---|
798 | // to have a normalized uniform mass==1 so the acceleration is F/M = F.
|
---|
799 | class ForceField {
|
---|
800 | public:
|
---|
801 | virtual Point3 Force(TimeValue t,const Point3 &pos, const Point3 &vel)=0;
|
---|
802 | };
|
---|
803 |
|
---|
804 | // A collision object can be applied to a particle system by a SpaceWarp.
|
---|
805 | // The collision object checks a particle's position and velocity and
|
---|
806 | // determines if the particle will colide with it in the next dt amount of
|
---|
807 | // time. If so, it modifies the position and velocity.
|
---|
808 | class CollisionObject {
|
---|
809 | public:
|
---|
810 | // Check for collision. Return TRUE if there was a collision and the position and velocity have been modified.
|
---|
811 | virtual BOOL CheckCollision(TimeValue t,Point3 &pos, Point3 &vel, float dt)=0;
|
---|
812 | };
|
---|
813 |
|
---|
814 |
|
---|
815 | // The particle system class derived from GeomObject and still has
|
---|
816 | // GEOMOBJECT_CLASS_ID as its super class.
|
---|
817 | //
|
---|
818 | // Given an object, to determine if it is a ParticleObject, call
|
---|
819 | // GetInterface() with the ID I_PARTICLEOBJ or use the macro
|
---|
820 | // GetParticleInterface(anim) which returns a ParticleObject* or NULL.
|
---|
821 | class ParticleObject: public GeomObject {
|
---|
822 | public:
|
---|
823 | virtual void ApplyForceField(ForceField *ff)=0;
|
---|
824 | virtual BOOL ApplyCollisionObject(CollisionObject *co)=0; // a particle can choose no to support this and return FALSE
|
---|
825 |
|
---|
826 | // A particle object IS deformable, but does not let itself be
|
---|
827 | // deformed using the usual GetPoint/SetPoint methods. Instead
|
---|
828 | // a space warp must apply a force field to deform the particle system.
|
---|
829 | int IsDeformable() {return TRUE;}
|
---|
830 |
|
---|
831 | // Particle objects don't actually do a shallow copy and therefore
|
---|
832 | // cannot be cached.
|
---|
833 | BOOL CanCacheObject() {return FALSE;}
|
---|
834 | };
|
---|
835 |
|
---|
836 | //----------------------------------------------------------------------
|
---|
837 |
|
---|
838 |
|
---|
839 | /*-------------------------------------------------------------------
|
---|
840 | ShapeObject: these are the open or closed hierarchical shape objects.
|
---|
841 | ---------------------------------------------------------------------*/
|
---|
842 |
|
---|
843 | class PolyShape;
|
---|
844 | class BezierShape;
|
---|
845 | class MeshCapInfo;
|
---|
846 | class PatchCapInfo;
|
---|
847 | class ShapeHierarchy;
|
---|
848 |
|
---|
849 | // This class may be requested in the pipeline via the GENERIC_SHAPE_CLASS_ID,
|
---|
850 | // also set up in the Class_ID object genericShapeClassID
|
---|
851 |
|
---|
852 | // Options for steps in MakePolyShape (>=0: Use fixed steps)
|
---|
853 | #define PSHAPE_BUILTIN_STEPS -2 // Use the shape's built-in steps/adaptive settings (default)
|
---|
854 | #define PSHAPE_ADAPTIVE_STEPS -1 // Force adaptive steps
|
---|
855 |
|
---|
856 | class ShapeObject: public Object {
|
---|
857 | public:
|
---|
858 | virtual int IntersectRay(TimeValue t, Ray& ray, float& at)=0;
|
---|
859 | virtual void InitNodeName(TSTR& s) { s = _T("Shape"); }
|
---|
860 | SClass_ID SuperClassID() { return SHAPE_CLASS_ID; }
|
---|
861 | int IsRenderable() { return(0); }
|
---|
862 | // Access methods
|
---|
863 | virtual int NumberOfCurves()=0; // Number of curve polygons in the shape
|
---|
864 | virtual BOOL CurveClosed(TimeValue t, int curve)=0; // Returns TRUE if the curve is closed
|
---|
865 | virtual Point3 InterpCurve3D(TimeValue t, int curve, float param)=0; // Interpolate from 0-1 on a curve
|
---|
866 | virtual Point3 TangentCurve3D(TimeValue t, int curve, float param)=0; // Get tangent at point on a curve
|
---|
867 | virtual float LengthOfCurve(TimeValue t, int curve)=0; // Get the length of a curve
|
---|
868 | virtual int NumberOfPieces(TimeValue t, int curve)=0; // Number of sub-curves in a curve
|
---|
869 | virtual Point3 InterpPiece3D(TimeValue t, int curve, int piece, float param)=0; // Interpolate from 0-1 on a sub-curve
|
---|
870 | virtual Point3 TangentPiece3D(TimeValue t, int curve, int piece, float param)=0; // Get tangent on a sub-curve
|
---|
871 | virtual BOOL CanMakeBezier() { return FALSE; } // Return TRUE if can turn into a bezier representation
|
---|
872 | virtual void MakeBezier(TimeValue t, BezierShape &shape) {} // Create the bezier representation
|
---|
873 | virtual ShapeHierarchy &OrganizeCurves(TimeValue t, ShapeHierarchy *hier=NULL)=0; // Ready for lofting, extrusion, etc.
|
---|
874 | virtual void MakePolyShape(TimeValue t, PolyShape &shape, int steps = PSHAPE_BUILTIN_STEPS, BOOL optimize = FALSE)=0; // Create a PolyShape representation with optional fixed steps & optimization
|
---|
875 | virtual int MakeCap(TimeValue t, MeshCapInfo &capInfo, int capType)=0; // Generate mesh capping info for the shape
|
---|
876 | virtual int MakeCap(TimeValue t, PatchCapInfo &capInfo) { return 0; } // Only implement if CanMakeBezier=TRUE -- Gen patch cap info
|
---|
877 | private:
|
---|
878 | };
|
---|
879 |
|
---|
880 | /*-------------------------------------------------------------------
|
---|
881 | WSMObject : This is the helper object for the WSM modifier
|
---|
882 | ---------------------------------------------------------------------*/
|
---|
883 |
|
---|
884 | class WSMObject: public Object {
|
---|
885 | public:
|
---|
886 | SClass_ID SuperClassID() { return WSM_OBJECT_CLASS_ID; }
|
---|
887 | virtual Modifier *CreateWSMMod(INode *node)=0;
|
---|
888 | virtual int UsesWireColor() { return FALSE; } // TRUE if the object color is used for display
|
---|
889 | private:
|
---|
890 | };
|
---|
891 |
|
---|
892 |
|
---|
893 | class ControlMatrix3;
|
---|
894 |
|
---|
895 | // Used with EnumModContexts()
|
---|
896 | class ModContextEnumProc {
|
---|
897 | public:
|
---|
898 | virtual BOOL proc(ModContext *mc)=0; // Return FALSE to stop, TRUE to continue.
|
---|
899 | };
|
---|
900 |
|
---|
901 | /*-------------------------------------------------------------------
|
---|
902 | Modifier: these are the ObjectSpace and World Space modifiers: They are
|
---|
903 | subclassed off of BaseObject so that they can put up a graphical
|
---|
904 | representation in the viewport.
|
---|
905 | ---------------------------------------------------------------------*/
|
---|
906 |
|
---|
907 | class Modifier: public BaseObject {
|
---|
908 | friend class ModNameRestore;
|
---|
909 | TSTR modName;
|
---|
910 | public:
|
---|
911 |
|
---|
912 | CoreExport virtual TSTR GetName();
|
---|
913 | CoreExport virtual void SetName(TSTR n);
|
---|
914 |
|
---|
915 | SClass_ID SuperClassID() { return OSM_CLASS_ID; }
|
---|
916 |
|
---|
917 | // Disables all mod apps that reference this modifier _and_ have a select
|
---|
918 | // anim flag turned on.
|
---|
919 | void DisableModApps() { NotifyDependents(FOREVER,PART_OBJ,REFMSG_DISABLE); }
|
---|
920 | void EnableModApps() { NotifyDependents(FOREVER,PART_OBJ,REFMSG_ENABLE); }
|
---|
921 |
|
---|
922 | // This disables or enables the mod. All mod apps referencing will be affected.
|
---|
923 | void DisableMod() {
|
---|
924 | SetAFlag(A_MOD_DISABLED);
|
---|
925 | NotifyDependents(FOREVER,PART_ALL|PART_OBJECT_TYPE,REFMSG_CHANGE);
|
---|
926 | }
|
---|
927 | void EnableMod() {
|
---|
928 | ClearAFlag(A_MOD_DISABLED);
|
---|
929 | NotifyDependents(FOREVER,PART_ALL|PART_OBJECT_TYPE,REFMSG_CHANGE);
|
---|
930 | }
|
---|
931 | int IsEnabled() { return !TestAFlag(A_MOD_DISABLED); }
|
---|
932 |
|
---|
933 | CoreExport virtual Interval LocalValidity(TimeValue t);
|
---|
934 | virtual ChannelMask ChannelsUsed()=0;
|
---|
935 | virtual ChannelMask ChannelsChanged()=0;
|
---|
936 | // this is used to invalidate cache's in Edit Modifiers:
|
---|
937 | virtual void NotifyInputChanged(Interval changeInt, PartID partID, RefMessage message, ModContext *mc) {}
|
---|
938 |
|
---|
939 | // This is the method that is called when the modifier is needed to
|
---|
940 | // apply its effect to the object. Note that the INode* is always NULL
|
---|
941 | // for object space modifiers.
|
---|
942 | virtual void ModifyObject(TimeValue t, ModContext &mc, ObjectState* os, INode *node)=0;
|
---|
943 |
|
---|
944 | // this should return FALSE for things like edit modifiers
|
---|
945 | virtual int NeedUseSubselButton() { return 1; }
|
---|
946 |
|
---|
947 | // Modifiers that place a dependency on topology should return TRUE
|
---|
948 | // for this method. An example would be a modifier that stores a selection
|
---|
949 | // set base on vertex indices.
|
---|
950 | virtual BOOL DependOnTopology(ModContext &mc) {return FALSE;}
|
---|
951 |
|
---|
952 | // this can return:
|
---|
953 | // DEFORM_OBJ_CLASS_ID -- not really a class, but so what
|
---|
954 | // MAPPABLE_OBJ_CLASS_ID -- ditto
|
---|
955 | // TRIOBJ_CLASS_ID
|
---|
956 | // BEZIER_PATCH_OBJ_CLASS_ID
|
---|
957 | virtual Class_ID InputType()=0;
|
---|
958 |
|
---|
959 | virtual void ForceNotify(Interval& i)
|
---|
960 | {NotifyDependents(i,ChannelsChanged(),REFMSG_CHANGE );}
|
---|
961 |
|
---|
962 | virtual IOResult SaveLocalData(ISave *isave, LocalModData *ld) { return IO_OK; }
|
---|
963 | virtual IOResult LoadLocalData(ILoad *iload, LocalModData **pld) { return IO_OK; }
|
---|
964 |
|
---|
965 | // These handle loading and saving the modifier name. Should be called
|
---|
966 | // by derived class BEFORE it loads or saves any chunks
|
---|
967 | CoreExport IOResult Save(ISave *isave);
|
---|
968 | CoreExport IOResult Load(ILoad *iload);
|
---|
969 |
|
---|
970 | // This will call proc->proc once for each application of the modifier.
|
---|
971 | CoreExport void EnumModContexts(ModContextEnumProc *proc);
|
---|
972 | private:
|
---|
973 | };
|
---|
974 |
|
---|
975 | class OSModifier: public Modifier {
|
---|
976 | public:
|
---|
977 | SClass_ID SuperClassID() { return OSM_CLASS_ID; }
|
---|
978 | };
|
---|
979 |
|
---|
980 | class WSModifier: public Modifier {
|
---|
981 | public:
|
---|
982 | SClass_ID SuperClassID() { return WSM_CLASS_ID; }
|
---|
983 | };
|
---|
984 |
|
---|
985 | void CoreExport MakeHitRegion(HitRegion& hr, int type, int crossing, int epsi, IPoint2 *p);
|
---|
986 |
|
---|
987 | class PolyLineProc {
|
---|
988 | public:
|
---|
989 | virtual int proc(Point3 *p, int n)=0;
|
---|
990 | virtual void SetLineColor(float r, float g, float b) {}
|
---|
991 | };
|
---|
992 |
|
---|
993 | class DrawLineProc:public PolyLineProc {
|
---|
994 | GraphicsWindow *gw;
|
---|
995 | public:
|
---|
996 | DrawLineProc() { gw = NULL; }
|
---|
997 | DrawLineProc(GraphicsWindow *g) { gw = g; }
|
---|
998 | int proc(Point3 *p, int n) { gw->polyline(n, p, NULL, NULL, 0, NULL); return 0; }
|
---|
999 | void SetLineColor(float r, float g, float b) {gw->setColor(LINE_COLOR,r,g,b);}
|
---|
1000 | };
|
---|
1001 |
|
---|
1002 | class BoxLineProc:public PolyLineProc {
|
---|
1003 | Box3 box;
|
---|
1004 | Matrix3 *tm;
|
---|
1005 | public:
|
---|
1006 | BoxLineProc() { box.Init();}
|
---|
1007 | BoxLineProc(Matrix3* m) { tm = m; box.Init(); }
|
---|
1008 | Box3& Box() { return box; }
|
---|
1009 | CoreExport int proc(Point3 *p, int n);
|
---|
1010 | };
|
---|
1011 |
|
---|
1012 |
|
---|
1013 | // Apply the PolyLineProc to each edge (represented by an array of Point3's) of the box
|
---|
1014 | // after passing it through the Deformer def.
|
---|
1015 | void CoreExport DoModifiedBox(Box3& box, Deformer &def, PolyLineProc& lp);
|
---|
1016 | void CoreExport DoModifiedLimit(Box3& box, float z, int axis, Deformer &def, PolyLineProc& lp);
|
---|
1017 | void CoreExport DrawCenterMark(PolyLineProc& lp, Box3& box );
|
---|
1018 |
|
---|
1019 | // Some functions to draw mapping icons
|
---|
1020 | void CoreExport DoSphericalMapIcon(BOOL sel,float radius, PolyLineProc& lp);
|
---|
1021 | void CoreExport DoCylindricalMapIcon(BOOL sel,float radius, float height, PolyLineProc& lp);
|
---|
1022 | void CoreExport DoPlanarMapIcon(BOOL sel,float width, float length, PolyLineProc& lp);
|
---|
1023 |
|
---|
1024 | //---------------------------------------------------------------------
|
---|
1025 | // Data structures for keeping log of hits during sub-object hit-testing.
|
---|
1026 | //---------------------------------------------------------------------
|
---|
1027 |
|
---|
1028 | class HitLog;
|
---|
1029 | class HitRecord {
|
---|
1030 | friend class HitLog;
|
---|
1031 | HitRecord *next;
|
---|
1032 | public:
|
---|
1033 | INode *nodeRef;
|
---|
1034 | ModContext *modContext;
|
---|
1035 | DWORD distance;
|
---|
1036 | ulong hitInfo;
|
---|
1037 | HitData *hitData;
|
---|
1038 | HitRecord() { next = NULL; modContext = NULL; distance = 0; hitInfo = 0; hitData = NULL;}
|
---|
1039 | HitRecord(INode *nr, ModContext *mc, DWORD d, ulong inf, HitData *hitdat) {
|
---|
1040 | next = NULL;
|
---|
1041 | nodeRef = nr; modContext = mc; distance = d; hitInfo = inf; hitData = hitdat;
|
---|
1042 | }
|
---|
1043 | HitRecord(HitRecord *n,INode *nr, ModContext *mc, DWORD d, ulong inf, HitData *hitdat) {
|
---|
1044 | next = n;
|
---|
1045 | nodeRef = nr; modContext = mc; distance = d; hitInfo = inf; hitData = hitdat;
|
---|
1046 | }
|
---|
1047 | HitRecord * Next() { return next; }
|
---|
1048 | ~HitRecord() { if (hitData) { delete hitData; hitData = NULL; } }
|
---|
1049 | };
|
---|
1050 |
|
---|
1051 | class HitLog {
|
---|
1052 | HitRecord *first;
|
---|
1053 | public:
|
---|
1054 | HitLog() { first = NULL; }
|
---|
1055 | ~HitLog() { Clear(); }
|
---|
1056 | CoreExport void Clear();
|
---|
1057 | HitRecord* First() { return first; }
|
---|
1058 | CoreExport HitRecord* ClosestHit();
|
---|
1059 | CoreExport void LogHit(INode *nr, ModContext *mc, DWORD dist, ulong info, HitData *hitdat = NULL);
|
---|
1060 | };
|
---|
1061 |
|
---|
1062 |
|
---|
1063 | // Creates a new empty derived object, sets it to point at the given
|
---|
1064 | // object and returns a pointer to the derived object.
|
---|
1065 | CoreExport Object *MakeObjectDerivedObject(Object *obj);
|
---|
1066 |
|
---|
1067 | #endif //_OBJECT_
|
---|