source: cpp/gdk/modelparts.h @ 70

Last change on this file since 70 was 66, checked in by Maciej Komosinski, 14 years ago

set 'eol-style' to 'native'

  • Property svn:eol-style set to native
File size: 15.6 KB
Line 
1// This file is a part of the Framsticks GDK library.
2// Copyright (C) 2002-2011  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ 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 effector colour for this neuro unit */
244   EffectorClass=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);
351PARAMGETDEF(classObject);
352#undef STATRICKCLASS
353
354SyntParam classProperties();
355// base properties:
356long refno; ///< unique reference number (former 'neuro' refno)
357
358long part_refno; ///< can be used by some items as the part ref#
359long joint_refno; ///< can be used by some items as the joint ref#
360
361Pt3D pos,rot;   ///< default = zero
362
363ModelUserTags userdata;
364
365Neuro();
366Neuro(double _state,double _inertia,double _force,double _sigmo);
367Neuro(const Neuro& src):PartBase(getDefaultStyle()) {operator=(src);}
368
369~Neuro();
370
371void operator=(const Neuro& src);
372
373/** Attach this Neuro to the specified Part or detach it from the body if p==NULL.
374    Neuro can be attached to either Part or Joint, but not both.
375    @see getPart()
376 */
377void attachToPart(Part* p) {part=p; joint=0;}
378
379/** Attach this Neuro to the specified Joint or detach it from the body if p==NULL.
380    Neuro can be attached to either Part or Joint, but not both.
381    @see getJoint()
382 */
383void attachToJoint(Joint* j) {joint=j; part=0;}
384
385void attachToPart(int i);
386void attachToJoint(int i);
387
388/** @return Part the Neuro is attached to, or NULL if it has no defined location on the body.
389    @see attachToPart()
390 */
391Part *getPart() {return part;}
392
393/** @return Joint the Neuro is attached to, or NULL if it has no defined location on the body.
394    @see attachToJoint()
395 */
396Joint *getJoint() {return joint;}
397
398int isOldEffector();
399int isOldReceptor();
400int isOldNeuron();
401int isNNConnection();
402
403/** @return the number of inputs connected to this Neuro.
404    Functions like getInput(), getInputWeight() will accept connection number [0..InputCount-1]
405 */
406int getInputCount() const {return inputs.size();}
407
408/// @return the number of output connections (including possible self-connections)
409int getOutputsCount() const;
410
411/** @return the Neuro connected as i-th input */
412Neuro* getInput(int i) const {return (i>=inputs.size())?0:inputs(i).n;}
413/** @return the Neuro connected as i-th input.
414    @param weight
415 */
416Neuro* getInput(int i,float &weight) const;
417/** @return connectin weight for i-th input */
418float getInputWeight(int i) const;
419/** change connection weight for i-th input */
420void setInputWeight(int i,float weight);
421/** connect i-th input with another neuron */
422void setInput(int i,Neuro*n);
423/** connect i-th input with another neuron */
424void setInput(int i,Neuro*n,float weight);
425/** add new input. @return its reference number */
426int addInput(Neuro* child,float weight=1.0,const SString* info=0);
427/** @return reference number [0..InputCount-1] of the input
428   or -1 if 'child' is not connected with this Neuro.*/
429int findInput(Neuro* child) const;
430void removeInput(int refno);
431/**    @return reference number of the child connection, like findInput() */
432int removeInput(Neuro* child);
433
434int findInputs(SList& result,const char* classname=0,const Part* part=0,const Joint* joint=0) const;
435int findOutputs(SList& result,const char* classname=0,const Part* part=0,const Joint* joint=0) const;
436
437/* class database retrieval */
438static int getClassCount();
439/** @return Neuro class name.
440    @param classindex 0 .. getClassCount()
441 */
442static SString getClassName(int classindex);
443static NeuroClass* getClass(int classindex);
444static NeuroClass* getClass(const SString& classname);
445static int getClassIndex(const NeuroClass*nc);
446
447#ifdef MODEL_V1_COMPATIBLE
448friend class OldItems;
449long neuro_refno; ///< parent ref# (called neuro_refno for compatibility with old Neuro class), @see moredata
450long conn_refno; ///< the other neuron ref# in N-N connections, can be used by some other items
451double weight; ///< weight of the N-N connection and (all?) receptors
452double inertia,force,sigmo; //!!!
453
454/** @deprecated provided only for compatibility with old Neuro/NeuroItem classes.
455    use getInputCount() instead. @sa getInputCount() */
456int getItemCount() {return oldItems().getItemCount();}
457
458/** @deprecated provided only for compatibility with old Neuro/NeuroItem classes.
459    use getInput() instead. @sa getInput() */
460NeuroItem* getNeuroItem(int i) {return oldItems().getNeuroItem(i);}
461#endif
462
463  protected:
464#ifdef MODEL_V1_COMPATIBLE
465/** old Neuro compatibility */
466OldItems* olditems;
467OldItems& oldItems() {if (!olditems) olditems=new OldItems(*this); return *olditems;}
468void invalidateOldItems() {if (olditems) olditems->freelist();}
469#endif
470
471  public:
472
473// not really private, but you should not access those directly
474double state;
475
476/** may reference parent neuron if parentcount is exacty 1. parent is invalid otherwise. @sa parentcount */
477Neuro *parent;
478int parentcount; ///< @sa parent
479
480Part *part;     ///< link to the Part
481Joint *joint;   ///< link to the Joint - required by some objects (eg.muscles)
482Orient o;       ///< rotation matrix calculated from "rot"
483static ParamEntry emptyParamTab[];
484};
485
486#ifdef MODEL_V1_COMPATIBLE
487class NeuroItem;
488
489/// for compatibility with old NeuroItem class.
490class NeuroItem: public Neuro
491{
492public:
493NeuroItem() {}
494};
495#endif
496
497class NeuroExt: public Neuro
498{
499  public:
500#define STATRICKCLASS NeuroExt
501PARAMGETDEF(neuroclass);
502PARAMSETDEF(neuroclass);
503#undef STATRICKCLASS
504static ParamEntry *getParamTab();
505};
506
507class NeuroConn
508{
509  public:
510int n1_refno,n2_refno;
511double weight;
512SString info;
513NeuroConn();
514};
515
516extern ParamEntry f0_part_paramtab[],f0_joint_paramtab[],f0_nodeltajoint_paramtab[],f0_neuro_paramtab[],f0_neuroconn_paramtab[],f0_neuroitem_paramtab[];
517extern Param st_neuroparam,st_jointparam,st_partparam;
518
519#endif
Note: See TracBrowser for help on using the repository browser.