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

Last change on this file since 171 was 171, checked in by sz, 10 years ago

getObjectTarget is now the recommended way to retrieve object from ExtValue?, can post the standard warning message about missing object

  • 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) 2002-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.