source: cpp/frams/model/modelparts.h @ 650

Last change on this file since 650 was 544, checked in by Maciej Komosinski, 8 years ago

Renamed:
Model::getShape() ==> Model::getShapeType()
Model::SHAPE_OLD ==> Model::SHAPE_BALL_AND_STICK
Model::SHAPE_NEW ==> Model::SHAPE_SOLIDS
Part::SHAPE_DEFAULT ==> Part::SHAPE_BALL_AND_STICK
Joint::SHAPE_DEFAULT ==> Joint::SHAPE_BALL_AND_STICK
Joint::SHAPE_SOLID ==> Joint::SHAPE_FIXED

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