source: cpp/frams/vm/classes/3dobject.cpp @ 197

Last change on this file since 197 was 197, checked in by Maciej Komosinski, 10 years ago

GDK used by developers since 1999, distributed on the web since 2002

  • Property svn:eol-style set to native
File size: 16.1 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 1999-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include <frams/util/3d.h>
6#include "3dobject.h"
7#include <frams/param/param.h>
8#include "collectionobj.h"
9
10ParamEntry* Pt3D_Ext::getStaticParamtab()
11{
12#define FIELDSTRUCT Pt3D_Ext
13static ParamEntry paramtab[]=
14{
15{"XYZ",1,18,"XYZ","3D vector"},
16
17{"x",0,PARAM_NOSTATIC,"x","f",FIELD(p.x),},
18{"y",0,PARAM_NOSTATIC,"y","f",FIELD(p.y),},
19{"z",0,PARAM_NOSTATIC,"z","f",FIELD(p.z),},
20{"new",0,0,"create new XYZ object","p oXYZ(f x,f y,f z)",PROCEDURE(p_new),"3D vectors objects can be also created using the (x,y,z) notation, i.e. var v=(1,2,3) is the same as var v=XYZ.new(1,2,3);",},
21{"newFromVector",0,0,"create new XYZ object","p oXYZ(oVector)",PROCEDURE(p_newFromVector),"used for deserialization"},
22{"clone",0,PARAM_NOSTATIC,"create new XYZ object copying the coordinates","p oXYZ()",PROCEDURE(p_clone),"Note: copying object references does not create new objects. Use clone() if a new object is needed.\n\nExample:\nvar o1=(1,2,3), o2=o1, o3=o1.clone();\no1.y=9999;\n//o2 is now (1,9999,3) but o3 is still (1,2,3)",},
23{"set",0,PARAM_NOSTATIC,"set (copy) coordinates from another XYZ object","p(oXYZ)",PROCEDURE(p_set),},
24{"set3",0,PARAM_NOSTATIC,"set individual 3 coordinates","p(f x,f y,f z)",PROCEDURE(p_set3),},
25{"add",0,PARAM_NOSTATIC,"add","p(oXYZ)",PROCEDURE(p_addvec),"Note: it does not return a new object, just modifies the existing one"},
26{"sub",0,PARAM_NOSTATIC,"subtract","p(oXYZ)",PROCEDURE(p_subvec),"Note: it does not return a new object, just modifies the existing one"},
27{"scale",0,PARAM_NOSTATIC,"multiply by scalar","p(f)",PROCEDURE(p_scale),},
28{"length",0,PARAM_READONLY+PARAM_NOSTATIC,"length","f",GETONLY(length),},
29{"normalize",0,PARAM_NOSTATIC,"normalize","p()",PROCEDURE(p_normalize),"scales the vector length to 1.0"},
30{"toString",0,PARAM_READONLY+PARAM_NOSTATIC,"textual form","s",GETONLY(toString),},
31{"toVector",0,PARAM_READONLY+PARAM_NOSTATIC,"vector of [x,y,z]","oVector",GETONLY(toVector),},
32{"rotate",0,PARAM_NOSTATIC,"rotate using Orient object","p(oOrient)",PROCEDURE(p_rotate),},
33{"revRotate",0,PARAM_NOSTATIC,"reverse rotate using Orient object","p(oOrient)",PROCEDURE(p_revrotate),},
34{"get",0,PARAM_NOSTATIC,"get one of coordinates","p f(d index)",PROCEDURE(p_get),"this function makes the XYZ objects \"indexable\" (so you can use [] for accessing subsequent fields, like in Vector)",},
35{0,0,0,},
36};
37#undef FIELDSTRUCT
38return paramtab;
39}
40
41void Pt3D_Ext::p_new(ExtValue *args,ExtValue *ret)
42{
43*ret=makeDynamicObject(new Pt3D_Ext(args[2].getDouble(),args[1].getDouble(),args[0].getDouble()));
44}
45
46static double doubleFromVec(VectorObject *vec,int i)
47{
48if (i>=vec->data.size()) return 0;
49ExtValue *v=(ExtValue*)vec->data.get(i);
50if (v)
51        return v->getDouble();
52return 0;
53}
54
55static Pt3D pt3DFromVec(VectorObject* v,int offset=0)
56{
57return Pt3D(doubleFromVec(v,offset),doubleFromVec(v,offset+1),doubleFromVec(v,offset+2));
58}
59
60void Pt3D_Ext::p_newFromVector(ExtValue *args,ExtValue *ret)
61{
62VectorObject *vec=VectorObject::fromObject(args->getObject());
63if (vec)
64        *ret=makeDynamicObject(new Pt3D_Ext(pt3DFromVec(vec)));
65else
66        ret->setEmpty();
67}
68
69void Pt3D_Ext::p_clone(ExtValue *args,ExtValue *ret)
70{
71*ret=makeDynamicObject(new Pt3D_Ext(p.x,p.y,p.z));
72}
73
74void Pt3D_Ext::p_set3(ExtValue *args,ExtValue *ret)
75{
76p.x=args[2].getDouble();
77p.y=args[1].getDouble();
78p.z=args[0].getDouble();
79ret->setEmpty();
80}
81
82void Pt3D_Ext::p_set(ExtValue *args,ExtValue *ret)
83{
84Pt3D_Ext *other=fromObject(args[0]);
85if (other)
86        p=other->p;
87ret->setEmpty();
88}
89
90void Pt3D_Ext::get_length(ExtValue *ret)
91{
92ret->setDouble(p.length());
93}
94
95void Pt3D_Ext::get_toString(ExtValue *ret)
96{
97SString s="(";
98ExtValue v;
99v.setDouble(p.x); s+=v.getString();
100s+=",";
101v.setDouble(p.y); s+=v.getString();
102s+=",";
103v.setDouble(p.z); s+=v.getString();
104s+=")";
105ret->setString(s);
106}
107
108static void add3Coords(VectorObject* vec,const Pt3D& p)
109{
110vec->data+=new ExtValue(p.x);
111vec->data+=new ExtValue(p.y);
112vec->data+=new ExtValue(p.z);
113}
114
115void Pt3D_Ext::get_toVector(ExtValue *ret)
116{
117VectorObject *vec=new VectorObject;
118add3Coords(vec,p);
119ret->setObject(ExtObject(&VectorObject::par,vec));
120}
121
122void Pt3D_Ext::p_addvec(ExtValue *args,ExtValue *ret)
123{
124Pt3D_Ext *other=fromObject(args[0]);
125if (other)
126        p+=other->p;
127ret->setEmpty();
128}
129
130void Pt3D_Ext::p_subvec(ExtValue *args,ExtValue *ret)
131{
132Pt3D_Ext *other=fromObject(args[0]);
133if (other)
134        p-=other->p;
135ret->setEmpty();
136}
137
138void Pt3D_Ext::p_scale(ExtValue *args,ExtValue *ret)
139{
140double d=args[0].getDouble();
141p.x*=d; p.y*=d; p.z*=d;
142ret->setEmpty();
143}
144
145void Pt3D_Ext::p_normalize(ExtValue *args,ExtValue *ret)
146{
147p.normalize();
148ret->setEmpty();
149}
150
151void Pt3D_Ext::p_rotate(ExtValue *args,ExtValue *ret)
152{
153Orient_Ext *o=Orient_Ext::fromObject(args[0]);
154if (o)
155        {
156        Pt3D tmp=p;
157        o->o.transform(p,tmp);
158        }
159ret->setEmpty();
160}
161
162void Pt3D_Ext::p_revrotate(ExtValue *args,ExtValue *ret)
163{
164Orient_Ext *o=Orient_Ext::fromObject(args[0]);
165if (o)
166        {
167        Pt3D tmp=p;
168        o->o.revTransform(p,tmp);
169        }
170ret->setEmpty();
171}
172
173void Pt3D_Ext::p_get(ExtValue *args,ExtValue *ret)
174{
175int index=args->getInt();
176if ((index<0)||(index>2))
177        ret->setEmpty();
178else
179        ret->setDouble((&p.x)[index]);
180}
181
182Param& Pt3D_Ext::getStaticParam()
183{
184#ifdef __CODEGUARD__
185static Pt3D_Ext static_pt3dobj;
186static Param static_pt3dparam(getStaticParamtab(),&static_pt3dobj);
187#else
188static Param static_pt3dparam(getStaticParamtab());
189#endif
190return static_pt3dparam;
191}
192
193Pt3D_Ext* Pt3D_Ext::fromObject(const ExtValue& v)
194{
195return (Pt3D_Ext*)v.getObjectTarget(getStaticParam().getName());
196}
197
198ParamInterface* Pt3D_Ext::getInterface() {return &getStaticParam();}
199
200ExtObject Pt3D_Ext::makeStaticObject(Pt3D* p)
201{return ExtObject(&getStaticParam(),((char*)p)+(((char*)&p->x)-((char*)&((Pt3D_Ext*)p)->p.x)));}
202
203ExtObject Pt3D_Ext::makeDynamicObject(Pt3D_Ext* p)
204{return ExtObject(&getStaticParam(),p);}
205
206//////////////////////////////////////
207
208ParamEntry* Orient_Ext::getStaticParamtab()
209{
210#define FIELDSTRUCT Orient_Ext
211static ParamEntry paramtab[]=
212{
213{"Orient",1,27,"Orient","3D orientation, stored as 3x3 matrix."},
214
215{"xx",1,PARAM_NOSTATIC,"orientation.x.x","f",FIELD(o.x.x),},
216{"xy",1,PARAM_NOSTATIC,"orientation.x.y","f",FIELD(o.x.y),},
217{"xz",1,PARAM_NOSTATIC,"orientation.x.z","f",FIELD(o.x.z),},
218{"yx",1,PARAM_NOSTATIC,"orientation.y.x","f",FIELD(o.y.x),},
219{"yy",1,PARAM_NOSTATIC,"orientation.y.y","f",FIELD(o.y.y),},
220{"yz",1,PARAM_NOSTATIC,"orientation.y.z","f",FIELD(o.y.z),},
221{"zx",1,PARAM_NOSTATIC,"orientation.z.x","f",FIELD(o.z.x),},
222{"zy",1,PARAM_NOSTATIC,"orientation.z.y","f",FIELD(o.z.y),},
223{"zz",1,PARAM_NOSTATIC,"orientation.z.z","f",FIELD(o.z.z),},
224
225{"x",0,PARAM_NOSTATIC+PARAM_READONLY,"x vector","oXYZ",GETONLY(x),},
226{"y",0,PARAM_NOSTATIC+PARAM_READONLY,"y vector","oXYZ",GETONLY(y),},
227{"z",0,PARAM_NOSTATIC+PARAM_READONLY,"z vector","oXYZ",GETONLY(z),},
228
229{"new",0,0,"create new Orient object","p oOrient()",PROCEDURE(p_new),},
230{"newFromVector",0,0,"create new Orient object","p oOrient(oVector)",PROCEDURE(p_newFromVector),},
231{"toVector",0,PARAM_READONLY+PARAM_NOSTATIC,"vector representation","oVector",GETONLY(toVector),"for serialization"},
232{"clone",0,PARAM_NOSTATIC,"create new Orient object","p oOrient()",PROCEDURE(p_clone),},
233{"set",0,PARAM_NOSTATIC,"copy from another Orient object","p(oOrient)",PROCEDURE(p_set),},
234{"reset",0,PARAM_NOSTATIC,"set identity matrix","p()",PROCEDURE(p_reset),},
235{"rotate3",0,PARAM_NOSTATIC,"rotate around 3 axes","p(f x,f y,f z)",PROCEDURE(p_rotate3),},
236{"rotate",0,PARAM_NOSTATIC,"rotate using Orient object","p(oOrient)",PROCEDURE(p_rotate),},
237{"revRotate",0,PARAM_NOSTATIC,"reverse rotate using Orient object","p(oOrient)",PROCEDURE(p_revrotate),},
238{"lookAt",0,PARAM_NOSTATIC,"calculate rotation from 2 vectors","p(oXYZ direction,oXYZ up)",PROCEDURE(p_lookat),},
239{"normalize",0,PARAM_NOSTATIC,"normalize","p()",PROCEDURE(p_normalize),},
240{"between2",0,PARAM_NOSTATIC,"interpolate orientation","p(oOrient,oOrient,f amount)",PROCEDURE(p_between2),"The calling Orient receives the orientation interpolated from 2 input orientations.\nExample:\n"
241        "var o1=Orient.new(), o2=Orient.new(), o3=Orient.new();\n"
242        "o2.rotate3(0,Math.pi/2,0);\n"
243        "o3.between2(o1,o2,0); // o3 equals o2\n"
244        "o3.between2(o1,o2,1); // o3 equals o1\n"
245        "o3.between2(o1,o2,0.5); // o3 is halfway between o1 and o2\n"},
246{"betweenOV",0,PARAM_NOSTATIC,"interpolate orientation","p(oOrient,oXYZ,f amount)",PROCEDURE(p_betweenOV),"Like between2(), but the second Orient is composed of the supplied XYZ vector (X component) and Y Z vectors from the calling object.\n"
247        "Example:\n"
248        "var o=Orient.new();\n"
249        "o.betweenOV(o,(0,1,0),1); //no change, o remains 100 010 001\n"
250        "o.betweenOV(o,(0,1,0),0.9); //o is slightly rotated towards (0,1,0)\n"
251        "o.betweenOV(o,(0,1,0),0); //o is completely transformed, o.x=(0,1,0)\n"
252        },
253{"localToWorld",0,PARAM_NOSTATIC,"transform coordinates","p oXYZ(oXYZ point,oXYZ center)",PROCEDURE(p_localToWorld),},
254{"worldToLocal",0,PARAM_NOSTATIC,"transform coordinates","p oXYZ(oXYZ point,oXYZ center)",PROCEDURE(p_worldToLocal),},
255{0,0,0,},
256};
257#undef FIELDSTRUCT
258return paramtab;
259}
260
261void Orient_Ext::p_new(ExtValue *args,ExtValue *ret)
262{
263*ret=makeDynamicObject(new Orient_Ext());
264}
265
266void Orient_Ext::p_newFromVector(ExtValue *args,ExtValue *ret)
267{
268VectorObject *vec=VectorObject::fromObject(args->getObject());
269if (vec)
270        *ret=makeDynamicObject(new Orient_Ext(Orient(pt3DFromVec(vec,0),pt3DFromVec(vec,3),pt3DFromVec(vec,6))));
271else
272        ret->setEmpty();
273}
274
275void Orient_Ext::get_toVector(ExtValue *ret)
276{
277VectorObject *vec=new VectorObject;
278add3Coords(vec,o.x);
279add3Coords(vec,o.y);
280add3Coords(vec,o.z);
281ret->setObject(ExtObject(&VectorObject::par,vec));
282}
283
284void Orient_Ext::p_clone(ExtValue *args,ExtValue *ret)
285{
286*ret=makeDynamicObject(new Orient_Ext(o));
287}
288
289void Orient_Ext::p_set(ExtValue *args,ExtValue *ret)
290{
291Orient_Ext *other=fromObject(args[0]);
292if (other)
293        o=other->o;
294ret->setEmpty();
295}
296
297void Orient_Ext::p_reset(ExtValue *args,ExtValue *ret)
298{
299o=Orient_1;
300ret->setEmpty();
301}
302
303void Orient_Ext::get_x(PARAMGETARGS)
304{
305*ret=Pt3D_Ext::makeStaticObject(&o.x);
306}
307
308void Orient_Ext::get_y(PARAMGETARGS)
309{
310*ret=Pt3D_Ext::makeStaticObject(&o.y);
311}
312
313void Orient_Ext::get_z(PARAMGETARGS)
314{
315*ret=Pt3D_Ext::makeStaticObject(&o.z);
316}
317
318void Orient_Ext::p_lookat(ExtValue *args,ExtValue *ret)
319{
320Pt3D_Ext *dir=Pt3D_Ext::fromObject(args[1]),*up=Pt3D_Ext::fromObject(args[0]);
321if (dir&&up)
322        o.lookAt(dir->p,up->p);
323ret->setEmpty();
324}
325
326void Orient_Ext::p_rotate3(ExtValue *args,ExtValue *ret)
327{
328Pt3D p(args[2].getDouble(),args[1].getDouble(),args[0].getDouble());
329o.rotate(p);
330ret->setEmpty();
331}
332
333void Orient_Ext::p_rotate(ExtValue *args,ExtValue *ret)
334{
335Orient_Ext *obj=Orient_Ext::fromObject(args[0]);
336if (!obj)
337        {
338        Orient tmp=o;
339        obj->o.transform(o,tmp);
340        }
341ret->setEmpty();
342}
343
344void Orient_Ext::p_revrotate(ExtValue *args,ExtValue *ret)
345{
346Orient_Ext *obj=Orient_Ext::fromObject(args[0]);
347if (obj)
348        {
349        Orient tmp=o;
350        obj->o.revTransform(o,tmp);
351        }
352ret->setEmpty();
353}
354
355void Orient_Ext::p_normalize(ExtValue *args,ExtValue *ret)
356{
357o.normalize();
358ret->setEmpty();
359}
360
361void Orient_Ext::p_between2(ExtValue *args,ExtValue *ret)
362{
363Orient_Ext *o1=Orient_Ext::fromObject(args[2]);
364Orient_Ext *o2=Orient_Ext::fromObject(args[1]);
365if (o1&&o2)
366        {
367        double q1=args[0].getDouble(),q2=1.0-q1;
368        o.x.x=q1*o1->o.x.x+q2*o2->o.x.x;
369        o.x.y=q1*o1->o.x.y+q2*o2->o.x.y;
370        o.x.z=q1*o1->o.x.z+q2*o2->o.x.z;
371        o.y.x=q1*o1->o.y.x+q2*o2->o.y.x;
372        o.y.y=q1*o1->o.y.y+q2*o2->o.y.y;
373        o.y.z=q1*o1->o.y.z+q2*o2->o.y.z;
374        o.z.x=q1*o1->o.z.x+q2*o2->o.z.x;
375        o.z.y=q1*o1->o.z.y+q2*o2->o.z.y;
376        o.z.z=q1*o1->o.z.z+q2*o2->o.z.z;
377        o.normalize();
378        }
379ret->setEmpty();
380}
381
382void Orient_Ext::p_betweenOV(ExtValue *args,ExtValue *ret)
383{
384Orient_Ext *o1=Orient_Ext::fromObject(args[2]);
385Pt3D_Ext *p2=Pt3D_Ext::fromObject(args[1]);
386if (o1&&p2)
387        {
388        double q1=args[0].getDouble(),q2=1.0-q1;
389        o.x.x=q1*o1->o.x.x+q2*p2->p.x;
390        o.x.y=q1*o1->o.x.y+q2*p2->p.y;
391        o.x.z=q1*o1->o.x.z+q2*p2->p.z;
392        o.normalize();
393        }
394ret->setEmpty();
395}
396
397void Orient_Ext::p_localToWorld(ExtValue *args,ExtValue *ret)
398{
399Pt3D_Ext *center,*point;
400point=Pt3D_Ext::fromObject(args[1]);
401center=Pt3D_Ext::fromObject(args[0]);
402if (center && point)
403        {
404        Pt3D d;
405        Pt3D src=point->p;
406        o.transform(d,src);
407        d+=center->p;
408        *ret=Pt3D_Ext::makeDynamicObject(new Pt3D_Ext(d));
409        }
410else
411        ret->setEmpty();
412}
413
414void Orient_Ext::p_worldToLocal(ExtValue *args,ExtValue *ret)
415{
416Pt3D_Ext *center,*point;
417point=Pt3D_Ext::fromObject(args[1]);
418center=Pt3D_Ext::fromObject(args[0]);
419if (center && point)
420        {
421        Pt3D d;
422        Pt3D src=point->p;
423        d-=center->p;
424        o.revTransform(d,src);
425        *ret=Pt3D_Ext::makeDynamicObject(new Pt3D_Ext(d));
426        }
427else
428        ret->setEmpty();
429}
430
431Param& Orient_Ext::getStaticParam()
432{
433#ifdef __CODEGUARD__
434static Orient_Ext static_orientobj;
435static Param static_orientparam(getStaticParamtab(),&static_orientobj);
436#else
437static Param static_orientparam(getStaticParamtab());
438#endif
439return static_orientparam;
440}
441
442Orient_Ext* Orient_Ext::fromObject(const ExtValue& v)
443{
444return (Orient_Ext*)v.getObjectTarget(getStaticParam().getName());
445}
446
447ParamInterface* Orient_Ext::getInterface() {return &getStaticParam();}
448
449ExtObject Orient_Ext::makeStaticObject(Orient* o)
450{return ExtObject(&getStaticParam(),((char*)o)+(((char*)&o->x)-((char*)&((Orient_Ext*)o)->o.x)));}
451
452ExtObject Orient_Ext::makeDynamicObject(Orient_Ext* p)
453{return ExtObject(&getStaticParam(),p);}
454
455ParamEntry* ReferenceObj::getStaticParamtab()
456{
457#define FIELDSTRUCT ReferenceObj
458static ParamEntry paramtab[]=
459{
460{"Ref",1,5,"Ref","Reference objects. Useful for returning things from functions.\n\nExample:\nvar x=111;\nsquare(&x);// '&' creates the Reference object\nSimulator.print(x);//x is now 12321\n\nfunction square(r)\n{r.value=r.value*r.value;}\n//square receives the Reference objects and changes its 'value' field"},
461
462{"value",0,PARAM_NOSTATIC,"value","x",GETSET(value),},
463{"newS",0,0,"create new reference","p",PROCEDURE(p_newS),"(for internal use only) use &variablename to create Ref objects.",},
464{"newO",0,0,"create new reference","p",PROCEDURE(p_newO),"(for internal use only) use &variablename to create Ref objects.",},
465{"copyFrom",0,0,"copy the reference","p(oRef)",PROCEDURE(p_copyFrom),"make the reference point to the same target,"},
466{"toString",0,PARAM_READONLY+PARAM_NOSTATIC,"textual form","s",GETONLY(toString),},
467{0,0,0,},
468};
469#undef FIELDSTRUCT
470return paramtab;
471}
472
473Param& ReferenceObj::getStaticParam()
474{
475#ifdef __CODEGUARD__
476static ReferenceObj static_referenceobj;
477static Param static_refobjectparam(getStaticParamtab(),&static_referenceobj);
478#else
479static Param static_refobjectparam(getStaticParamtab());
480#endif
481return static_refobjectparam;
482}
483
484void ReferenceObj::p_newS(ExtValue *args,ExtValue *ret)
485{
486*ret=makeDynamicObject(new ReferenceObj((ExtValue*)args->getInt()));
487}
488
489void ReferenceObj::p_newO(ExtValue *args,ExtValue *ret)
490{
491if (args[0].type==TInt)
492        *ret=makeDynamicObject(new ReferenceObj(args[1].getObject(),args[0].getInt()));
493else
494        *ret=makeDynamicObject(new ReferenceObj(args[1].getObject(),args[0].getString()));
495}
496
497void ReferenceObj::p_copyFrom(ExtValue *args,ExtValue *ret)
498{
499ReferenceObj* other=fromObject(args[0]);
500if (other)
501        {
502        value=other->value;
503        obj=other->obj;
504        prop=other->prop;
505        }
506}
507
508void ReferenceObj::get_toString(ExtValue *ret)
509{
510SString s="(";
511static SListTempl<ReferenceObj*> trace;
512if (trace.find(this)>=0)
513        s+="...";
514else
515        {
516        trace+=this;
517        if (value)
518                s+=value->getString();
519        else
520                {
521                ExtValue v;
522                Param tmp_param;
523                ParamInterface *pi=obj.getParamInterface(tmp_param);
524                pi->get(prop,v);
525                s+=v.getString();
526                }
527        trace-=this;
528        }
529s+=")";
530ret->setString(s);
531}
532
533void ReferenceObj::get_value(ExtValue *ret)
534{
535if (value)
536        *ret=*value;
537else
538        {
539        Param tmp_param;
540        ParamInterface *pi=obj.getParamInterface(tmp_param);
541        pi->get(prop,*ret);
542        }
543}
544
545int ReferenceObj::set_value(const ExtValue *val)
546{
547if (value)
548        *value=*val;
549else
550        {
551        Param tmp_param;
552        ParamInterface *pi=obj.getParamInterface(tmp_param);
553        pi->set(prop,*val);
554        }
555return PSET_CHANGED;
556}
557
558ReferenceObj::ReferenceObj(const ExtObject &o,const SString &p)
559        :value(0),obj(o)
560{
561Param tmp_param;
562ParamInterface *pi=obj.getParamInterface(tmp_param);
563prop=pi->findId(p);
564}
565
566ExtObject ReferenceObj::makeDynamicObject(ReferenceObj* r)
567{return ExtObject(&getStaticParam(),r);}
568
569ReferenceObj* ReferenceObj::fromObject(const ExtValue& v)
570{
571return (ReferenceObj*)v.getObjectTarget(getStaticParam().getName());
572}
Note: See TracBrowser for help on using the repository browser.