source: cpp/frams/model/modelparts.cpp @ 637

Last change on this file since 637 was 637, checked in by Maciej Komosinski, 6 years ago

Extended code so that NeuroClass? properties are described in more detail

  • Property svn:eol-style set to native
File size: 18.0 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include <stdlib.h>
6#include <math.h>
7#include <stdio.h>
8#include <string.h>
9#include <ctype.h>
10#include <time.h>
11#include <errno.h>
12
13///////////////////////////////     MODELPARTS.CPP     ///////////////
14
15#include "modelparts.h"
16#include "model.h"
17
18#include <common/nonstd.h>
19#include <frams/param/param.h>
20#include <frams/neuro/neurolibrary.h>
21#include <frams/util/multirange.h>
22#include <frams/util/extvalue.h>
23#include <frams/param/paramobj.h>
24
25#include F0_DEFASSIGN_FILE
26
27#ifndef SDK_WITHOUT_FRAMS
28#include <frams/neuro/neuroclsobject.h>
29#endif
30
31template<>
32char ModelUserTags::reg[5]={0};
33
34/////////////////////////
35
36PartBase::~PartBase()
37{if (mapped) delete mapped;}
38
39void PartBase::notifyMappingChange()
40{
41if (owner) owner->partmappingchanged=1;
42}
43
44void PartBase::setMapping(const IRange &r)
45{
46if (mapped) (*mapped)=r;
47else mapped=new MultiRange(r);
48notifyMappingChange();
49}
50
51void PartBase::clearMapping()
52{
53if (mapped) {delete mapped; mapped=0;}
54}
55
56void PartBase::addMapping(const IRange &r)
57{
58if (mapped) mapped->add(r);
59else mapped=new MultiRange(r);
60notifyMappingChange();
61}
62
63void PartBase::setMapping(const MultiRange &mr)
64{
65if (mapped) (*mapped)=mr;
66else mapped=new MultiRange(mr);
67notifyMappingChange();
68}
69
70void PartBase::addMapping(const MultiRange &mr)
71{
72if (mapped) mapped->add(mr);
73else mapped=new MultiRange(mr);
74notifyMappingChange();
75}
76
77void PartBase::setInfo(const SString& name,const SString& value)
78{
79strSetField(info,name,value);
80}
81
82void PartBase::setInfo(const SString& name,int value)
83{
84setInfo(name,SString::valueOf(value));
85}
86
87void PartBase::setInfo(const SString& name,double value)
88{
89setInfo(name,SString::valueOf(value));
90}
91
92SString PartBase::getInfo(const SString& name)
93{
94return strGetField(info,name);
95}
96
97/////////////////////////
98
99NeuroClass::NeuroClass(ParamEntry *_props,SString _description,
100                       int _prefinputs,int _prefoutput,int _preflocation,
101                       int *_vectordata,bool own_vd,int vhints)
102        :ownedvectordata(own_vd),
103         name(_props->name),longname(_props->id),description(_description),
104         props(_props),ownedprops(false),
105         prefinputs(_prefinputs),
106         prefoutput(_prefoutput),
107         preflocation(_preflocation),
108         vectordata(_vectordata),
109         visualhints(vhints),impl_count(0),/*impl(0),*/active(1),genactive(0)
110{}
111
112NeuroClass::~NeuroClass()
113{
114setSymbolGlyph(0,0);
115if (props && ownedprops)
116        ParamObject::freeParamTab(props);
117}
118
119NeuroClass::NeuroClass()
120        :ownedvectordata(0),
121         name("Invalid"),
122         props(empty_paramtab),ownedprops(false),
123         prefinputs(0), prefoutput(0),
124         preflocation(0), vectordata(0),
125         visualhints(0),impl_count(0), /*impl(0),*/ active(1), genactive(0)
126{}
127
128SString NeuroClass::getSummary()
129{
130SString t;
131t=getDescription();
132if (t.len()) t+="\n\n";
133t+="Characteristics:\n";
134if(getPreferredInputs())
135        {
136        if (getPreferredInputs()<0) t+="   supports any number of inputs\n";
137        else if (getPreferredInputs()==1) t+="   uses single input\n";
138        else t+=SString::sprintf("   uses %d inputs\n",getPreferredInputs());
139        }
140else t+="   does not use inputs\n";
141if(getPreferredOutput())
142        t+="   provides output value\n";
143else
144        t+="   does not provide output value\n";
145switch(getPreferredLocation())
146        {
147        case 0: t+="   does not require location in body\n"; break;
148        case 1: t+="   should be located on a Part\n"; break;
149        case 2: t+="   should be located on a Joint\n"; break;
150        }
151Param p=getProperties();
152if (p.getPropCount())
153        {
154        if (t.len()) t+="\n\n";
155        t+="Properties:\n";
156        const char *h;
157        int i;
158        for(i=0;i<p.getPropCount();i++)
159                {
160                if (i) t+="\n";
161                t+="   "; t+=p.name(i); t+=" ("; t+=p.id(i); t+=")";
162                switch(*p.type(i))
163                        {
164                        case 'd': t+=" integer";
165                        {paInt a,b,c; int n=p.getMinMax(i,a,b,c); if (n>=2) t+=SString::sprintf(" %d..%d",a,b); if (n>=3) t+=SString::sprintf(" (default %d)",c);}
166                                break;
167                        case 'f': t+=" float";
168                        {double a,b,c; int n=p.getMinMax(i,a,b,c); if (n>=2) t+=SString::sprintf(" %g..%g",a,b); if (n>=3) t+=SString::sprintf(" (default %g)",c);}
169                                break;
170                        case 's': t+=" string";
171                        {int a,b; SString c; int n=p.getMinMax(i,a,b,c); if ((n>=2)&&(b>0)) t+=SString::sprintf(", max %d chars",b); if (n>=3) t+=SString::sprintf(" (default \"%s\")",c.c_str());}
172                                break;
173                        case 'x': t+=" anything"; break;
174                        }
175                if (h=p.help(i)) if (*h) {t+=" - "; t+=h;}
176                }
177        }
178return t;
179}
180
181/////////////////////////
182
183/////////////////////////////////////
184
185Neuro::Neuro(double _state,double _inertia,double _force,double _sigmo)
186        :PartBase(getDefaultStyle()),state(_state)
187#ifdef MODEL_V1_COMPATIBLE
188,inertia(_inertia),force(_force),sigmo(_sigmo)
189#endif
190{
191#ifdef MODEL_V1_COMPATIBLE
192olditems=0;
193#endif
194flags=0;
195myclass=0;
196knownclass=1;
197part_refno=-1; joint_refno=-1;
198}
199
200Neuro::Neuro(void):PartBase(getDefaultStyle())
201{
202defassign();
203state=0.0;
204myclass=NULL;
205myclassname="N";//default d="N" but f0.def is unable to set this (d is GETSET, not a regular FIELD)
206knownclass=0;
207refno=0;
208pos=Pt3D_0; rot=Pt3D_0;
209parent=0; part=0; joint=0;
210parentcount=0;
211#ifdef MODEL_V1_COMPATIBLE
212olditems=0;
213#endif
214flags=0;
215part_refno=-1; joint_refno=-1;
216}
217
218
219Neuro::~Neuro()
220{
221#ifdef MODEL_V1_COMPATIBLE
222if (olditems) delete olditems;
223#endif
224int i;
225for(i=0;i<inputs.size();i++)
226        {
227        NInput &ni=inputs(i);
228        if (ni.info) delete ni.info;
229        }
230}
231
232SString** Neuro::inputInfo(int i)
233{
234if (i>=getInputCount()) return 0;
235return &inputs(i).info;
236}
237
238void Neuro::setInputInfo(int i,const SString& name,const SString &value)
239{
240SString **s=inputInfo(i);
241if (!s) return;
242if (!*s) *s=new SString();
243strSetField(**s,name,value);
244}
245
246void Neuro::setInputInfo(int i,const SString& name,int value)
247{
248setInputInfo(i,name,SString::valueOf(value));
249}
250
251void Neuro::setInputInfo(int i,const SString& name,double value)
252{
253setInputInfo(i,name,SString::valueOf(value));
254}
255
256SString Neuro::getInputInfo(int i)
257{
258SString **s=inputInfo(i);
259if (!s) return SString();
260if (!*s) return SString();
261return **s;
262}
263
264SString Neuro::getInputInfo(int i,const SString& name)
265{
266SString **s=inputInfo(i);
267if (!s) return SString();
268if (!*s) return SString();
269return strGetField(**s,name);
270}
271
272void Neuro::operator=(const Neuro& src)
273{
274refno=src.refno;
275#ifdef MODEL_V1_COMPATIBLE
276neuro_refno=-1;
277conn_refno=-1;
278force=src.force;
279sigmo=src.sigmo;
280inertia=src.inertia;
281weight=src.weight;
282olditems=0;
283#endif
284state=src.state;
285part_refno=-1;
286joint_refno=-1;
287pos=src.pos; rot=src.rot;
288parent=0; part=0; joint=0;
289parentcount=0;
290flags=0;
291myclass=src.myclass;
292knownclass=src.knownclass;
293myclassname=src.myclassname;
294myclassparams=src.myclassparams;
295}
296
297void Neuro::attachToPart(int i)
298{attachToPart((i>=0)?owner->getPart(i):0);}
299
300void Neuro::attachToJoint(int i)
301{attachToJoint((i>=0)?owner->getJoint(i):0);}
302
303int Neuro::getClassCount()
304{return NeuroLibrary::staticlibrary.getClassCount();}
305
306NeuroClass* Neuro::getClass(int classindex)
307{return NeuroLibrary::staticlibrary.getClass(classindex);}
308
309NeuroClass* Neuro::getClass(const SString& classname)
310{return NeuroLibrary::staticlibrary.findClass(classname);}
311
312int Neuro::getClassIndex(const NeuroClass*nc)
313{return NeuroLibrary::staticlibrary.classes.find((void*)nc);}
314
315NeuroClass* Neuro::getClass()
316{
317checkClass();
318return myclass;
319}
320
321void Neuro::setClass(NeuroClass* cl)
322{
323myclass=cl;
324myclassname=cl->getName();
325knownclass=1;
326}
327
328SString Neuro::getClassName(int classindex)
329{
330NeuroClass *cl=NeuroLibrary::staticlibrary.getClass(classindex);
331return cl? cl->getName() : SString();
332}
333
334void Neuro::setDetails(const SString& details)
335{
336int colon=details.indexOf(':');
337if (colon>=0) {myclassname=details.substr(0,colon); myclassparams=details.substr(colon+1);}
338else {myclassname=details; myclassparams=0;}
339knownclass=0;
340}
341
342SString Neuro::getDetails()
343{
344SString ret=getClassName();
345if (myclassparams.len()) {if (!ret.len()) ret="N"; ret+=":"; ret+=myclassparams;}
346return ret;
347}
348
349void Neuro::checkClass()
350{
351if (knownclass) return;
352myclass=getClass(myclassname);
353knownclass=1;
354}
355
356SyntParam Neuro::classProperties(bool handle_defaults_when_saving)
357{
358NeuroClass *cl=getClass();
359ParamEntry *pe = cl ? cl->getParamTab() : emptyParamTab;
360return SyntParam(pe,&myclassparams,handle_defaults_when_saving);
361}
362
363SString Neuro::getClassName()
364{
365return myclassname;
366}
367
368void Neuro::setClassName(const SString& clazz)
369{
370myclassname=clazz;
371knownclass=0;
372}
373
374int Neuro::addInput(Neuro* child,double weight,const SString *info)
375{
376inputs+=NInput(child,weight,(info&&(info->len()))?new SString(*info):0);
377child->parentcount++;
378if (child->parentcount==1) {child->parent=this;}
379return inputs.size()-1;
380}
381
382int Neuro::findInput(Neuro* child) const
383{
384for(int i=0;i<inputs.size();i++)
385        if (inputs(i).n==child) return i;
386return -1;
387}
388
389Neuro* Neuro::getInput(int i,double &weight) const
390{
391if (i>=getInputCount()) return 0;
392NInput &inp=inputs(i);
393weight=inp.weight;
394return inp.n;
395}
396
397double Neuro::getInputWeight(int i) const
398{
399return inputs(i).weight;
400}
401
402void Neuro::setInputWeight(int i,double w)
403{
404inputs(i).weight=w;
405}
406
407void Neuro::setInput(int i,Neuro* n)
408{
409NInput &inp=inputs(i);
410inp.n=n;
411}
412
413void Neuro::setInput(int i,Neuro* n,double w)
414{
415NInput &inp=inputs(i);
416inp.n=n;
417inp.weight=w;
418}
419
420void Neuro::removeInput(int refno)
421{
422Neuro *child=getInput(refno);
423child->parentcount--;
424if (child->parent==this) child->parent=0;
425SString *s=inputs(refno).info;
426if (s) delete s;
427inputs.remove(refno);
428}
429
430int Neuro::removeInput(Neuro* child)
431{
432int i=findInput(child);
433if (i>=0) removeInput(i);
434return i;
435}
436
437int Neuro::getOutputsCount() const
438{
439   int c=0;
440   for(int i=0;i<owner->getNeuroCount();i++)
441     for(int j=0;j<owner->getNeuro(i)->getInputCount();j++) c+=owner->getNeuro(i)->getInput(j)==this;
442   return c;
443}
444
445int Neuro::isOldEffector()
446{
447static SString bend("|"),rot("@");
448return ((getClassName()==bend)||(getClassName()==rot));
449}
450
451int Neuro::isOldReceptor()
452{
453static SString g("G"),t("T"),s("S");
454return ((getClassName()==g)||(getClassName()==t)||(getClassName()==s));
455}
456
457int Neuro::isOldNeuron()
458{
459static SString n("N");
460return (getClassName()==n);
461}
462
463int Neuro::isNNConnection()
464{
465static SString conn("-");
466return (getClassName()==conn);
467}
468
469int Neuro::findInputs(SList& result,const char* classname,const Part* part,const Joint* joint) const
470{
471Neuro *nu;
472SString cn(classname);
473int n0=result.size();
474for(int i=0;nu=getInput(i);i++)
475        {
476        if (part)
477                if (nu->part != part) continue;
478        if (joint)
479                if (nu->joint != joint) continue;
480        if (classname)
481                if (nu->getClassName() != cn) continue;
482        result+=(void*)nu;
483        }
484return result.size()-n0;
485}
486
487int Neuro::findOutputs(SList& result,const char* classname,const Part* part,const Joint* joint) const
488{ // not very efficient...
489Neuro *nu,*inp;
490SString cn(classname);
491SList found;
492int n0=result.size();
493for(int i=0;nu=getModel().getNeuro(i);i++)
494        {
495        if (part)
496                if (nu->part != part) continue;
497        if (joint)
498                if (nu->joint != joint) continue;
499        if (classname)
500                if (inp->getClassName() != cn) continue;
501        for (int j=0;inp=nu->getInput(j);j++)
502                if (inp==this)
503                        {
504                        result+=(void*)nu;
505                        break;
506                        }
507        }
508return result.size()-n0;
509}
510
511void Neuro::get_inputCount(PARAMGETARGS)
512{ret->setInt(inputs.size());}
513
514void Neuro::p_getInputNeuroDef(ExtValue *args,ExtValue *ret)
515{
516int i=args->getInt();
517if ((i<0)||(i>=inputs.size()))
518        ret->setEmpty();
519else
520        ret->setObject(ExtObject(&Neuro::getStaticParam(),inputs(i).n));
521}
522
523void Neuro::p_getInputWeight(ExtValue *args,ExtValue *ret)
524{
525int i=args->getInt();
526if ((i<0)||(i>=inputs.size()))
527        ret->setEmpty();
528else
529        ret->setDouble(inputs(i).weight);
530}
531
532void Neuro::p_getInputNeuroIndex(ExtValue *args,ExtValue *ret)
533{
534int i=args->getInt();
535if ((i<0)||(i>=inputs.size()))
536        ret->setInt(-1);
537else
538        ret->setInt(inputs(i).n->refno);
539}
540
541void Neuro::get_classObject(PARAMGETARGS)
542{
543#ifndef SDK_WITHOUT_FRAMS
544NeuroClassExt::makeStaticObject(ret,getClass());
545#endif
546}
547
548/////// old items
549#ifdef MODEL_V1_COMPATIBLE
550void OldItems::buildlist()
551{ // guaranteed to work only for old NN layouts
552 // (neurons,neuro connections, old receptors and effectors)
553if (listok) return;
554 // inputs can contain both neuroitem connections (details="") and direct neuron references (details="N")
555 // in OldItems we create neuroitems freom direct references
556for(int i=0;i<neuro.getInputCount();i++)
557        {
558        float w;
559        Neuro *n=neuro.getInput(i,w);
560        if (n->isOldNeuron())
561                {
562                Neuro *ni=new Neuro();
563                ni->setClassName("-");
564                ni->weight=w;
565                ni->neuro_refno=neuro.refno;
566                ni->conn_refno=n->refno;
567                items+=ni;
568                syntitems+=ni;
569                }
570        else
571                {
572                items+=n;
573                n->weight=w;
574                }
575        }
576SList outputs;
577neuro.findOutputs(outputs);
578FOREACH(Neuro*,n,outputs)
579        {
580        if (n->isNNConnection() || n->isOldNeuron())
581                outputs-=n;
582        }
583items+=outputs;
584listok=1;
585}
586
587void OldItems::freelist()
588{
589FOREACH(Neuro*,n,syntitems)
590        delete n;
591syntitems.clear();
592items.clear();
593listok=0;
594}
595
596int OldItems::getItemCount()
597{
598buildlist();
599return items.size();
600}
601
602NeuroItem *OldItems::getNeuroItem(int i)
603{
604buildlist();
605return (NeuroItem*)items(i);
606}
607
608NeuroItem *OldItems::addNewNeuroItem()
609{
610Neuro *nu=neuro.getModel().addNewNeuro();
611nu->setClassName("-");
612if (listok) items+=nu;
613neuro.addInput(nu);
614return (NeuroItem*)nu;
615}
616
617int OldItems::findNeuroItem(NeuroItem *ni)
618{
619buildlist();
620return items.find((void*)ni);
621}
622#endif
623
624///////////////////////////////////////
625
626SString Part::getDefaultStyle()
627{return SString("part");}
628SString Joint::getDefaultStyle()
629{return SString("joint");}
630/*
631const SString& Neuro::getDefaultStyle()
632{static SString s("neuro"); return s;}
633const SString& NeuroItem::getDefaultStyle()
634{static SString s("neuroitem"); return s;}
635*/
636SString Neuro::getDefaultStyle()
637{return SString("neuro");}
638
639Part::Part(enum Shape s):PartBase(getDefaultStyle())
640{
641o=Orient_1;
642p=Pt3D_0;
643rot=Pt3D_0;
644flags=0;
645defassign();
646shape=s;
647mass=1;
648}
649
650void Part::operator=(const Part& src)
651{
652p=src.p; o=src.o;
653flags=src.flags;
654mass=src.mass; density=src.density;
655friction=src.friction;
656ingest=src.ingest;
657assim=src.assim;
658size=src.size;
659rot=src.rot;
660refno=src.refno;
661vcolor=src.vcolor;
662vsize=src.vsize;
663vis_style=src.vis_style;
664shape=src.shape;
665scale=src.scale;
666hollow=src.hollow;
667}
668
669void Part::setOrient(const Orient &_o)
670{
671o=_o;
672rot.getAngles(o.x,o.z);
673}
674
675void Part::setRot(const Pt3D &r)
676{
677rot=r;
678o=Orient_1;
679o.rotate(rot);
680}
681
682void Part::setPositionAndRotationFromAxis(const Pt3D &p1,const Pt3D &p2)
683{
684Pt3D x=p2-p1;
685Pt3D dir(x.y,x.z,x.x);
686p=p1+x*0.5;
687rot.getAngles(x,dir);
688}
689
690Param& Part::getStaticParam()
691{
692static Param p(f0_part_paramtab,0,"Part");
693return p;
694}
695
696
697///////////////////////////
698
699Joint::Joint():PartBase(getDefaultStyle())
700{
701rot=Pt3D_0;
702defassign();
703d.x=JOINT_DELTA_MARKER;
704d.y=JOINT_DELTA_MARKER;
705d.z=JOINT_DELTA_MARKER;
706part1=0; part2=0;
707flags=0;
708usedelta=0;
709}
710
711void Joint::operator=(const Joint& src)
712{
713rot=src.rot;
714d=src.d;
715shape=src.shape;
716stamina=src.stamina;
717stif=src.stif; rotstif=src.rotstif;
718vis_style=src.vis_style;
719vcolor=src.vcolor;
720part1=0; part2=0;
721flags=src.flags;
722usedelta=src.usedelta;
723refno=src.refno;
724}
725
726void Joint::attachToParts(Part* p1,Part* p2)
727{
728part1=p1;
729part2=p2;
730if (p1 && p2)
731        {
732        o=rot;
733        if (usedelta)
734                {
735                p1->o.transform(p2->o,o);
736//              p2->o.x=p1->o/o.x; p2->o.y=p1->o/o.y; p2->o.z=p1->o/o.z;
737                p2->p=p2->o.transform(d)+p1->p;
738                }
739        }
740}
741
742void Joint::attachToParts(int p1,int p2)
743{
744attachToParts((p1>=0)?owner->getPart(p1):0,(p2>=0)?owner->getPart(p2):0);
745}
746
747void Joint::resetDelta()
748{
749d=Pt3D(JOINT_DELTA_MARKER,JOINT_DELTA_MARKER,JOINT_DELTA_MARKER);
750}
751
752void Joint::resetDeltaMarkers()
753{
754if (d.x==JOINT_DELTA_MARKER) d.x=0;
755if (d.y==JOINT_DELTA_MARKER) d.y=0;
756if (d.z==JOINT_DELTA_MARKER) d.z=0;
757}
758
759void Joint::useDelta(bool use)
760{
761usedelta=use;
762}
763
764bool Joint::isDelta()
765{
766return usedelta;
767}
768
769Param& Joint::getStaticParam()
770{
771static Param p(f0_joint_paramtab,0,"Joint");
772return p;
773}
774
775
776/////////////////////////////////////////////////////////////////
777/////////////////////////////////////////////////////////////////
778
779#include F0_CLASSES_FILE
780
781#ifdef MODEL_V1_COMPATIBLE
782
783#define FIELDSTRUCT Neuro
784ParamEntry f0_old_neuro_tab[]=
785{
786{"Connections",2,6,"n",},
787{"Other properties",},
788{"p",0,0,"part ref#","d",FIELD(part_refno),},
789{"j",0,0,"joint ref#","d",FIELD(joint_refno),},
790{"s",1,0,"state","f",FIELD(state),},
791{"in",1,0,"Inertia","f",FIELD(inertia),},
792{"fo",1,0,"Force","f",FIELD(force),},
793{"si",1,0,"Sigmoid","f",FIELD(sigmo),},
794{0,0,0,},
795};
796#undef FIELDSTRUCT
797
798#define FIELDSTRUCT NeuroItem
799ParamEntry f0_neuroitem_paramtab[]=
800{
801{"Connections",3,12,"ni",},
802{"Geometry",},
803{"Other",},
804{"n",0,0,"neuron ref#","d",FIELD(neuro_refno),},
805{"c",2,0,"connection ref#","d",FIELD(conn_refno),},
806{"w",2,0,"connection weight","f",FIELD(weight),},
807{"p",0,0,"part ref#","d",FIELD(part_refno),},
808{"j",0,0,"joint ref#","d",FIELD(joint_refno),},
809{"px",1,0,"position.x","f",FIELD(pos.x),},
810{"py",1,0,"position.y","f",FIELD(pos.y),},
811{"pz",1,0,"position.z","f",FIELD(pos.z),},
812{"rx",1,0,"rotation.x","f",FIELD(rot.x),},
813{"ry",1,0,"rotation.y","f",FIELD(rot.y),},
814{"rz",1,0,"rotation.z","f",FIELD(rot.z),},
815{"d",2,0,"item details","s",GETSET(details),},
816{0,0,0,},
817};
818#undef FIELDSTRUCT
819#endif
820
821////////////////////////////////////////
822
823ParamEntry Neuro::emptyParamTab[]=
824{
825{"Undefined Neuro",1,0,"?",},
826{0,0,0,},
827};
828
829Param Part::extraProperties()
830{
831return Param(f0_part_xtra_paramtab,this);
832}
833
834Param Joint::extraProperties()
835{
836return Param(f0_joint_xtra_paramtab,this);
837}
838
839Param Neuro::extraProperties()
840{
841return Param(f0_neuro_xtra_paramtab,this);
842}
843
844Param Part::properties()
845{
846return Param(f0_part_paramtab,this);
847}
848
849Param Joint::properties()
850{
851return Param(usedelta?f0_joint_paramtab:f0_nodeltajoint_paramtab,this);
852}
853
854Param Neuro::properties()
855{
856return Param(f0_neuro_paramtab,this);
857}
858
859class NeuroExtParamTab: public ParamTab
860{
861  public:
862NeuroExtParamTab():ParamTab(f0_neuro_paramtab)
863        {
864#define FIELDSTRUCT NeuroExt
865        ParamEntry entry={"class",2,0,"neuro class","s",GETSET(neuroclass)};
866#undef FIELDSTRUCT
867        add(&entry);
868
869#define FIELDSTRUCT Neuro
870        ParamEntry entry2={"state",2,0,"state","f",FIELD(state)};
871#undef FIELDSTRUCT
872        add(&entry2);
873        }
874};
875
876Param& Neuro::getStaticParam()
877{
878static Param p(f0_neuro_paramtab,0,"NeuroDef");
879return p;
880}
881
882////////////////////////
883
884NeuroConn::NeuroConn()
885{
886defassign();
887}
888
889//////////////////////////////////////
890
891ParamEntry *NeuroExt::getParamTab()
892{
893static NeuroExtParamTab tab;
894return tab.getParamTab();
895}
896
897void NeuroExt::get_neuroclass(PARAMGETARGS)
898{ret->setString(getClassName());}
899
900int NeuroExt::set_neuroclass(PARAMSETARGS)
901{setClassName(arg->getString());return PSET_CHANGED;}
902
903
Note: See TracBrowser for help on using the repository browser.