source: cpp/gdk/modelparts.h @ 57

Last change on this file since 57 was 5, checked in by sz, 16 years ago

added the GDK (Genotype Development Kit)

File size: 15.6 KB
Line 
1// This file is a part of Framsticks GDK library.
2// Copyright (C) 2002-2006  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.frams.alife.pl/ for further information.
4
5#ifndef _MODELPARTS_H_
6#define _MODELPARTS_H_
7
8#include "3d.h"
9#include "genoconv.h"
10
11#include "extvalue.h"
12#include "list.h"
13#include "sstring.h"
14#include "sstringutils.h"
15#include "param.h"
16#include "syntparam.h"
17#include "usertags.h"
18#include "paramtabobj.h"
19
20#include <stdio.h>
21
22//#define MODEL_V1_COMPATIBLE
23
24class Model;
25class IRange;
26class MultiRange;
27
28typedef UserTags<Model,void*,5> ModelUserTags;
29
30/** Common base for model elements. */
31class PartBase
32{
33public:
34SString vis_style;
35PartBase(const SString& s):vis_style(s),mapped(0) {}
36~PartBase();
37static const SString& getDefaultStyle(){static SString s("none"); return s;}
38MultiRange *mapped;
39enum PartBaseFlags { Selected=1 };
40long flags;
41Model *owner;   ///< backlink to the model
42
43SString info;
44
45Model &getModel() const {return *owner;}
46
47ModelUserTags userdata;
48
49void notifyMappingChange();
50
51void clearMapping();
52MultiRange* getMapping() {return mapped;}
53void setMapping(const IRange &mr);
54void addMapping(const IRange &mr);
55void setMapping(const MultiRange &mr);
56void addMapping(const MultiRange &mr);
57
58void setInfo(const SString& name,const SString& value);
59void setInfo(const SString& name,int value);
60void setInfo(const SString& name,double value);
61SString getInfo(const SString& name);
62};
63
64/// Part is the only real physical object in the framsticks creature.
65/// You can use this class for querying and adjusting constructed
66/// model properties
67class Part: public PartBase
68{
69friend class Model;
70static const SString& getDefaultStyle();
71Part(double _mass,double _size,double _density,double _friction,double _ingest,double _assim)
72        :mass(_mass),size(_size),density(_density),friction(_friction),ingest(_ingest),assim(_assim),
73        PartBase(getDefaultStyle())
74        {}
75public:
76// base properties - have special meaning and therefore are often accessed directly for convenience
77Pt3D p;    ///< 3d coordinates of the part
78Orient o;  ///< orientation in 3d space (rotation matrix)
79/// ParamInterface object is preferred way to get/set other properties.
80ParamInterface &extraProperties();
81ParamInterface &properties();
82long refno;
83Pt3D rot;
84
85///
86double mass,size,density,friction,ingest,assim;
87Pt3D food;
88//SList points; // collistion points
89//Slist neurons; // "select * from owner->neurons where part=this" ;-)
90
91Part();
92Part(const Part& src):PartBase(getDefaultStyle()) {operator=(src);}
93void operator=(const Part& src);
94};
95
96/// Imaginary connection between two parts.
97/// Joint has no mass nor intertia but can transfer forces.
98class Joint: public PartBase
99{
100friend class Model;
101static const SString& getDefaultStyle();
102Joint(double _stamina,double _stif,double _rotstif,double _d)
103        :stamina(_stamina),stif(_stif),rotstif(_rotstif),PartBase(getDefaultStyle())
104        {d=Pt3D(_d,0,0);}
105public:
106// base properties:
107long p1_refno,p2_refno; ///< parts' reference numbers
108
109Part *part1,*part2;     ///< references to parts
110class Pt3D d;           ///< position delta between parts
111class Pt3D rot; ///< orientation delta between parts expressed as 3 angles
112
113Joint();
114Joint(const Joint& src):PartBase(getDefaultStyle()) {operator=(src);}
115void operator=(const Joint& src);
116
117/** connect two parts with this joint.
118    p2 position will be adjusted if delta option is in effect.
119    @see isDelta()
120  */
121void attachToParts(Part* p1,Part* p2);
122/// @see attachToParts(Part*,Part*)
123void attachToParts(int p1,int p2);
124
125/** discard delta information but don't disable delta flag.
126    delta will be calculated from parts positions during final consistency check.
127 */
128void resetDelta();
129
130/** enable or disable delta option.
131    delta value is not changed.
132 */
133void useDelta(int false_or_true);
134
135/** @return 1 if delta option is in effect.
136    @see useDelta(), resetDelta(), useDelta()
137*/
138int isDelta();
139
140/// ParamInterface object is preferred way to get/set other properties.
141ParamInterface &extraProperties();
142ParamInterface &properties();
143
144// do not touch these:
145long refno; ///< this joint's reference number
146double stamina;
147double stif,rotstif;    ///< stiffness for moving and bending forces
148class Orient o; ///< orientation delta between parts as rotation matrix
149/** flag: generated f0 should include delta data.
150    set by 'singlestep' if j: attributes use delta option */
151int usedelta;
152};
153
154#define JOINT_DELTA_MARKER 99999.0
155
156////////////////// NN /////////////////
157
158class NeuroClass;
159
160typedef UserTags<NeuroClass,void*,5> NeuroClassUserTags;
161
162/** Information about neuron class.
163 */
164class NeuroClass
165{
166bool ownedvectordata;
167void operator=(const NeuroClass& nosuchthich){}
168  public:
169SString name,longname,description;
170ParamEntry *props;
171long prefinputs,prefoutput;
172long preflocation;
173int *vectordata;
174long visualhints;
175
176void *impl;
177bool active;
178int genactive;
179NeuroClassUserTags userdata;
180
181//////////////////////
182~NeuroClass();
183NeuroClass();
184NeuroClass(ParamEntry *_props,SString _description,
185           int _prefinputs,int _prefoutput,int _preflocation,int *_vectordata,bool own_vd=1,int vhints=0);
186/** class name for use in Neuro::setClassName(), Neuro::setDetails() (former 'moredata' field),
187    eg. "N","-",G" */
188const SString& getName() {return name;}
189/** human friendly name, eg. "Neuron","Link","Gyroscope"  */
190const SString& getLongName() {return longname;}
191/** long description */
192const SString& getDescription() {return description;}
193ParamEntry* getParamTab() {return props;}
194
195/** NeuroClass specific properties, recognized by all neurons of this class */
196Param getProperties() {return Param(props);}
197
198/** preferred number of inputs, -1 = no preference (any number will go).
199    extra inputs may be ignored by the object (depends on the class).
200 */
201int getPreferredInputs() {return prefinputs;}
202
203/** @return 0 if this object doesn't provide useful output signal. */
204int getPreferredOutput() {return prefoutput;}
205
206/** @return 0 if the object doesn't need any assignment to the body element.
207    @return 1 = it likes to be attached to the Part ( @see Neuro::attachToPart() )
208    @return 2 = the object prefers to have the Joint ( @see Neuro::attachToJoint() )
209 */
210int getPreferredLocation() {return preflocation;}
211/** vector drawing to be used in neuro net diagram.
212    interpretation:
213       {   
214           LEN = datalength (excluding this number)
215           NL = number_of_lines
216line#1 ->  NS = number_of_segments, x1,y1, x2,y2, ... xNS-1,yNS-1,
217         ...
218line#NL -> NS = number_of_segments, x1,y1, x2,y2, ... xNS-1,yNS-1,
219       }
220 */
221int* getSymbolGlyph()
222 {return vectordata;}
223void setSymbolGlyph(int *data,bool owned=1)
224 {if (vectordata&&ownedvectordata) delete []vectordata;
225 vectordata=data; ownedvectordata=owned;}
226/** additional information about how the neuron should be drawn
227    used by structure view (and maybe some other components).
228    return value is defined by the enum Hint
229    @see enum Hint
230 */
231int getVisualHints()
232 {return visualhints;}
233
234enum Hint
235        /** don't draw neurons of this class */
236 { Invisible=1,
237        /** don't draw classname label below the neuron */
238   DontShowClass=2,
239        /** draw the neuron at the first part when attached to joint (default is in the middle) */
240   AtFirstPart=4,
241        /** draw the neuron at the second part when attached to joint (default is in the middle) */
242   AtSecondPart=8,
243        /** use muscle colour for this neuro unit */
244   MuscleClass=16,
245        /** use receptor colour for this neuro unit */
246   ReceptorClass=32,
247   V1BendMuscle=64,
248   V1RotMuscle=128
249 };
250
251/** textual summary, automatically generated from other properties (like the neuro class tooltip) */
252SString getSummary();
253};
254
255class Neuro;
256
257#ifdef MODEL_V1_COMPATIBLE
258class NeuroItem;
259
260/** for compatibility with old Neuro/NeuroItem  */
261class OldItems
262{
263Neuro &neuro;
264SList syntitems; ///< to be deleted
265SList items;
266int listok;
267  public:
268OldItems(Neuro &n):neuro(n),listok(0) {}
269~OldItems() {freelist();}
270void buildlist();
271void freelist();
272
273int getItemCount();
274NeuroItem *getNeuroItem(int i);
275NeuroItem *addNewNeuroItem();
276int findNeuroItem(NeuroItem *n);
277};
278#endif
279
280/** Single processing unit in framsticks NN.  */
281class Neuro: public PartBase
282{
283friend class Model;
284static const SString& getDefaultStyle();
285
286struct NInput { Neuro *n; double weight; SString *info;
287        NInput(Neuro *_n,double w,SString *i=0):n(_n),weight(w),info(i) {} };
288
289SListTempl<NInput> inputs;
290
291NeuroClass *myclass;
292bool knownclass;
293SString myclassname, myclassparams;
294/** set myclass and make knownclass=true */
295void checkClass();
296
297SString** inputInfo(int i);
298
299public:
300enum NeuroFlags { HoldState=2 };
301ParamInterface &properties();
302ParamInterface &extraProperties();
303
304void setInputInfo(int i,const SString& name,const SString &value);
305void setInputInfo(int i,const SString& name,int value);
306void setInputInfo(int i,const SString& name,double value);
307SString getInputInfo(int i);
308SString getInputInfo(int i,const SString& name);
309
310NeuroClass* getClass();
311void setClass(NeuroClass*);
312
313SString getClassParams() {return myclassparams;}
314void setClassParams(const SString& cp) {myclassparams=cp;}
315
316SString getClassName();
317void setClassName(const SString& clazz);
318
319/** return neuro unit details encoded as <CLASS> ":" <PROPERTIES>
320   
321    new Neuro can be created as root object (without parent) or can be
322    the child of existing Neuro. Children of the Neuro are its inputs.
323    Standard framsticks neuron calculates the sum of all input units - other processing
324    units don't have to treat them equally and can even ignore some of them.
325    There are hints about expected inputs in the class database, @see getClass
326
327    Application should not assume anything about classes and its properties
328    except for two standard classes: (information about all current classes
329    can be retrieved with getClass/getClassProperties methods)
330    - getClassName()="N" is the standard framsticks neuron, accepts any number of inputs,
331      compatible with old Neuro object
332    - getClassName()="-" is the neuron link, compatible with old Neuro-Neuro link
333      (NeuroItem with empty details)
334    Empty details defaults to "-" if the parent unit is specified,
335    and "N" if the unit has no parent.
336 */
337SString getDetails();
338
339/** details = classname + ":" + classparams
340    @see getDetails()
341 */
342void setDetails(const SString&);
343
344#define STATRICKCLASS Neuro
345PARAMGETDEF(details) {arg1->setString(getDetails());}
346PARAMSETDEF(details) {setDetails(arg1->getString());return PSET_CHANGED;}
347PARAMGETDEF(inputCount);
348PARAMPROCDEF(p_getInputNeuroDef);
349PARAMPROCDEF(p_getInputNeuroIndex);
350PARAMPROCDEF(p_getInputWeight);
351#undef STATRICKCLASS
352
353SyntParam classProperties();
354// base properties:
355long refno; ///< unique reference number (former 'neuro' refno)
356
357long part_refno; ///< can be used by some items as the part ref#
358long joint_refno; ///< can be used by some items as the joint ref#
359
360Pt3D pos,rot;   ///< default = zero
361
362ModelUserTags userdata;
363
364Neuro();
365Neuro(double _state,double _inertia,double _force,double _sigmo);
366Neuro(const Neuro& src):PartBase(getDefaultStyle()) {operator=(src);}
367
368~Neuro();
369
370void operator=(const Neuro& src);
371
372/** Attach this Neuro to the specified Part or detach it from the body if p==NULL.
373    Neuro can be attached to either Part or Joint, but not both.
374    @see getPart()
375 */
376void attachToPart(Part* p) {part=p; joint=0;}
377
378/** Attach this Neuro to the specified Joint or detach it from the body if p==NULL.
379    Neuro can be attached to either Part or Joint, but not both.
380    @see getJoint()
381 */
382void attachToJoint(Joint* j) {joint=j; part=0;}
383
384void attachToPart(int i);
385void attachToJoint(int i);
386
387/** @return Part the Neuro is attached to, or NULL if it has no defined location on the body.
388    @see attachToPart()
389 */
390Part *getPart() {return part;}
391
392/** @return Joint the Neuro is attached to, or NULL if it has no defined location on the body.
393    @see attachToJoint()
394 */
395Joint *getJoint() {return joint;}
396
397int isOldEffector();
398int isOldReceptor();
399int isOldNeuron();
400int isNNConnection();
401
402/** @return the number of inputs connected to this Neuro.
403    Functions like getInput(), getInputWeight() will accept connection number [0..InputCount-1]
404 */
405int getInputCount() const {return inputs.size();}
406
407/// @return the number of output connections (including possible self-connections)
408int getOutputsCount() const;
409
410/** @return the Neuro connected as i-th input */
411Neuro* getInput(int i) const {return (i>=inputs.size())?0:inputs(i).n;}
412/** @return the Neuro connected as i-th input.
413    @param weight
414 */
415Neuro* getInput(int i,float &weight) const;
416/** @return connectin weight for i-th input */
417float getInputWeight(int i) const;
418/** change connection weight for i-th input */
419void setInputWeight(int i,float weight);
420/** connect i-th input with another neuron */
421void setInput(int i,Neuro*n);
422/** connect i-th input with another neuron */
423void setInput(int i,Neuro*n,float weight);
424/** add new input. @return its reference number */
425int addInput(Neuro* child,float weight=1.0,const SString* info=0);
426/** @return reference number [0..InputCount-1] of the input
427   or -1 if 'child' is not connected with this Neuro.*/
428int findInput(Neuro* child) const;
429void removeInput(int refno);
430/**    @return reference number of the child connection, like findInput() */
431int removeInput(Neuro* child);
432
433int findInputs(SList& result,const char* classname=0,const Part* part=0,const Joint* joint=0) const;
434int findOutputs(SList& result,const char* classname=0,const Part* part=0,const Joint* joint=0) const;
435
436/* class database retrieval */
437static int getClassCount();
438/** @return Neuro class name.
439    @param classindex 0 .. getClassCount()
440 */
441static SString getClassName(int classindex);
442static NeuroClass* getClass(int classindex);
443static NeuroClass* getClass(const SString& classname);
444static int getClassIndex(const NeuroClass*nc);
445
446#ifdef MODEL_V1_COMPATIBLE
447friend class OldItems;
448long neuro_refno; ///< parent ref# (called neuro_refno for compatibility with old Neuro class), @see moredata
449long conn_refno; ///< the other neuron ref# in N-N connections, can be used by some other items
450double weight; ///< weight of the N-N connection and (all?) receptors
451double inertia,force,sigmo; //!!!
452
453/** @deprecated provided only for compatibility with old Neuro/NeuroItem classes.
454    use getInputCount() instead. @sa getInputCount() */
455int getItemCount() {return oldItems().getItemCount();}
456
457/** @deprecated provided only for compatibility with old Neuro/NeuroItem classes.
458    use getInput() instead. @sa getInput() */
459NeuroItem* getNeuroItem(int i) {return oldItems().getNeuroItem(i);}
460#endif
461
462  protected:
463#ifdef MODEL_V1_COMPATIBLE
464/** old Neuro compatibility */
465OldItems* olditems;
466OldItems& oldItems() {if (!olditems) olditems=new OldItems(*this); return *olditems;}
467void invalidateOldItems() {if (olditems) olditems->freelist();}
468#endif
469
470  public:
471
472// not really private, but you should not access those directly
473double state;
474
475/** may reference parent neuron if parentcount is exacty 1. parent is invalid otherwise. @sa parentcount */
476Neuro *parent;
477int parentcount; ///< @sa parent
478
479Part *part;     ///< link to the Part
480Joint *joint;   ///< link to the Joint - required by some objects (eg.muscles)
481Orient o;       ///< rotation matrix calculated from "rot"
482static ParamEntry emptyParamTab[];
483};
484
485#ifdef MODEL_V1_COMPATIBLE
486class NeuroItem;
487
488/// for compatibility with old NeuroItem class.
489class NeuroItem: public Neuro
490{
491public:
492NeuroItem() {}
493};
494#endif
495
496class NeuroExt: public Neuro
497{
498  public:
499#define STATRICKCLASS NeuroExt
500PARAMGETDEF(neuroclass);
501PARAMSETDEF(neuroclass);
502#undef STATRICKCLASS
503static ParamEntry *getParamTab();
504};
505
506class NeuroConn
507{
508  public:
509int n1_refno,n2_refno;
510double weight;
511SString info;
512NeuroConn();
513};
514
515extern ParamEntry f0_part_paramtab[],f0_joint_paramtab[],f0_nodeltajoint_paramtab[],f0_neuro_paramtab[],f0_neuroconn_paramtab[],f0_neuroitem_paramtab[];
516extern Param st_neuroparam,st_jointparam,st_partparam;
517
518#endif
Note: See TracBrowser for help on using the repository browser.