Difference between revisions of "ShipEditor"
Mezzodaemon  (Talk | contribs)   | 
				|||
| (7 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
| − | + | (mostly obsolete, will be coded mainly in lua now, some ideas might be used though)  | |
| + | |||
| + | >= OLM =  | ||
* ObjectOriented-Lowpoly-Modeller  | * ObjectOriented-Lowpoly-Modeller  | ||
| − | * Prism Based -  | + | * Prism Based -> enhanced Interior Detection and Mesh-Management  | 
| − | ===   | + | == Headers ==  | 
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | <code>  | |
| − | + | class iSmartPointable<class _T> {  | |
| − | + | 	public:  | |
| − | //   | + | 	void RegisterSmartPtr	(SmartPtr<_T>* p);  | 
| − | //   | + | 	void UnregisterSmartPtr	(SmartPtr<_T>* p);  | 
| + | 	SmartPtr<_T>* GetSmartPtr (iSmartPtrListener* listener);  | ||
| + | |||
| + | 	protected:  | ||
| + | 	std::List<SmartPtr<_T>*>	smartPointers;  | ||
| + | 	iSmartPointable();							// empty, protected (must inherit)  | ||
| + | 	~iSmartPointable();							// calls NotifyDestroy() of all smartPointers  | ||
| + | 	void NotifySmartPtrChange(const int code);	// calls NotifyChange() of all smartPointers (idea)  | ||
| + | }  | ||
| − | + | class iSmartPtrListener<class _T> {  | |
| − | void	  | + | 	public :  | 
| + | 	virtual void	NotifySmartPtrDestroy	(SmartPtr<_T>* sp);  | ||
| + | 	virtual void	NotifySmartPtrChange	(SmartPtr<_T>* sp,const int code);  | ||
| + | }  | ||
| − | SmartPtr  | + | class SmartPtr<class _T> {  | 
| − | + | 	public :  | |
| − | iSmartPtrListener* listener; //   | + | 	SmartPtr	(_T* target=0,iSmartPtrListener<_T>* listener=0);  // target=0 possible !!!  (register)  | 
| − | + | 	~SmartPtr 	();  						//  (unregister)  | |
| − | + | 	void	SetTarget		(_T* target)	// unregister old + register new  | |
| − | void	NotifyDestroy	(); //   | + | 	void	NotifyDestroy	();				// calls listener->NotifyDestroy()  | 
| − | //   | + | 	_T& operator = (_T* cmp)				// test for equality  | 
| − | + | 	_T& operator = (SmartPtr<_T> cmp)		// test for equality  | |
| + | 	_T& operator * ()						// todo : lookup syntax for (*smartptr), something like (int dummy)  | ||
| + | 	_T& operator -> ()  | ||
| + | |||
| + | 	private :  | ||
| + | 	_T*					target; // _T must be iSmartPointable, can be 0  | ||
| + | 	iSmartPtrListener*	listener; // can be 0  | ||
| + | }  | ||
| + | </code>  | ||
| − | + | <code>  | |
| − | + | class iEditable {   | |
| − | + | 	public :  | |
| − | + | 	virtual void	Move	(Vec3 v);    | |
| − | + | 	virtual void	Scale	(Vec3 v,Vec3 o = gVec3Zero); //  might not operate on vertices !  | |
| − | + | 	virtual void	Rotate	(Vec3 v,Vec3 o = gVec3Zero);  | |
| − | + | 	virtual void	Rotate	(Quaternion q,Vec3 o = gVec3Zero);  | |
| − | + | 	// void transform(matrix m) ?  might not operate on vertices (cockpit-component is iEditable)  | |
| − | + | }  | |
| − | + | </code>  | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | <code>  | |
| − | + | class iMeshLike : public iEditable {   | |
| − | list	GetLinkedSides(SideNum);  | + | 	public :  | 
| − | list	GetLinkedVertices(VertexNum);  | + | 	virtual Vec3&	EditVertex		(const int i); // throws exception if index out of bounds  | 
| − | list	GetLinkedEdges(EdgeNum);  | + | 	virtual int		CountVertices	();  | 
| − | list	GetSideVertices(SideNum);  | + | 	Vec3	GetBoundsMin	();  | 
| − | list	GetEdgeVertices(EdgeNum);  | + | 	Vec3	GetBoundsMax	();  | 
| − | vertex,side,edge enumeration and access  | + | 	Vec3	GetBoundsCenter	();  | 
| − | editable functions  | + | 	Vec3	GetPivot		();  | 
| − | position+rotation access -  | + | |
| − | flags for lock vertices, lock pos/rot...  | + | 	// todo : readonly lists or complete management in this class ?  | 
| − | + | 	// usecase :  ship-frame(readwrite) cockpit(readonly:just one dockable side, and move/rotatable for complete object)  | |
| − | + | 	list	GetLinkedSides(SideNum);  | |
| − | + | 	list	GetLinkedVertices(VertexNum);  | |
| − | + | 	list	GetLinkedEdges(EdgeNum);  | |
| − | + | 	list	GetSideVertices(SideNum);  | |
| − | + | 	list	GetEdgeVertices(EdgeNum);  | |
| − | + | 	vertex,side,edge enumeration and access  | |
| − | // visual feedback(side/edge/face hilighting, gizmos...) implemented in this class ??  | + | 	editable functions  | 
| − | + | 	position+rotation access -> coordinate conversion + align rotation.  | |
| + | 	flags for lock vertices, lock pos/rot...  | ||
| + | 		cockpit is model with one designated side for docking,  | ||
| + | 			vertices cannot be changed, but position+rotation change is possible  | ||
| + | 		framecomponent does not need to use rotation, as the vertices are usualle freely movable  | ||
| + | 		when docked to cockpit, and moving the docked side, try to rotate/move the cockpit  | ||
| + | 			as closely as possible, then readjust vertices  | ||
| + | 		also otpional "lock form/vertices" for completed frame components (only rotate/position)  | ||
| + | 			-> behave similar to cockpit  | ||
| + | 	// visual feedback(side/edge/face hilighting, gizmos...) implemented in this class ??  | ||
| + | }  | ||
| + | </code>  | ||
| − | + | <code>  | |
| − | + | class cComponent {  | |
| − | SmartPtr  | + | 	public:  | 
| − | position,rotation  | + | 	SmartPtr<cComponent> parent; // =0 for top, frame:group,maschine:frame,...  | 
| − | GetBounds()  | + | 	position,rotation  | 
| − | GenBluePrint(tex,axis,offset,scale,colors)  | + | 	GetBounds()  | 
| − | Cast2Group()  | + | 	GenBluePrint(tex,axis,offset,scale,colors)  | 
| − | Cast2Frame()  | + | 	Cast2Group()  | 
| − | ComponentType*	type;  | + | 	Cast2Frame()  | 
| − | // emissions for sensors....  | + | 	ComponentType*	type;  | 
| − | // blueprint status display : functionality and damage  | + | 	// emissions for sensors....  | 
| − | NotifyDamage(); // Section (groupname) has been hit..  | + | 	// blueprint status display : functionality and damage  | 
| − | GetDescription();  | + | 	NotifyDamage(); // Section (groupname) has been hit..  | 
| − | // also baseclass for inner-maschinery etc...  | + | 	GetDescription();  | 
| − | // coordinate translation ! (rotation)  | + | 	// also baseclass for inner-maschinery etc...  | 
| − | //intersection,inclusion-calc  | + | 	// coordinate translation ! (rotation)  | 
| − | + | 	//intersection,inclusion-calc  | |
| + | }  | ||
| + | </code>  | ||
| − | + | <code>  | |
| − | + | class cFrameComponent : public iMeshLike {  | |
| − | list  | + | 	public:  | 
| − | list  | + | 	list<Vec3>		top;  | 
| − | int				flags;  | + | 	list<Vec3>		bot;  | 
| − | EditComponent	GetEditComponent	(); // null or overridden  | + | 	int				flags;  | 
| − | + | 	EditComponent	GetEditComponent	(); // null or overridden  | |
| + | }  | ||
| + | </code>  | ||
| − | + | <code>  | |
| − | + | class cModuleComponent : public iMeshLike {   | |
| − | list  | + | 	public:  | 
| − | // throws exceptions on illegal edit  | + | 	list<list<Vec3>>	sides;  | 
| − | // cockpit, solarpanel...  | + | 	// throws exceptions on illegal edit  | 
| − | + | 	// cockpit, solarpanel...  | |
| + | 	// ??? iMeshLike -> iEditable outside editor (deform from hit ??)  | ||
| + | }  | ||
| + | </code>  | ||
| − | + | <code>  | |
| − | + | class cComponentType {  | |
| − | // SteelFrame,TitanFrame,Cockpit...  | + | 	public:  | 
| − | + | 	// SteelFrame,TitanFrame,Cockpit...  | |
| + | }  | ||
| + | </code>  | ||
| − | + | <code>  | |
| − | + | class cEditComponent {  | |
| − | // lists for selected vertices,edges,sides and whole FrameComponent  | + | 	public:  | 
| − | + | 	// lists for selected vertices,edges,sides and whole FrameComponent  | |
| + | }  | ||
| + | </code>  | ||
| − | + | <code>  | |
| − | + | class cSelection : iEditable {  | |
| − | // Selection != Group, as selection can be mutliple vertices/faces/lines...  | + | 	public:  | 
| − | + | 	// Selection != Group, as selection can be mutliple vertices/faces/lines...  | |
| + | }  | ||
| + | </code>  | ||
| − | + | <code>  | |
| − | + | class cComponentGroup {  | |
| − | list  | + | 	public:  | 
| − | + | 	std::string	name;  | |
| + | 	std::list<Component> elements;  | ||
| + | }  | ||
| + | </code>  | ||
| − | + | <code>  | |
| − | EditComponentGroup  | + | class EditComponentGroup {  | 
| − | // type of elements = EditComponent, use Component-  | + | 	public:  | 
| − | + | 	// type of elements = EditComponent, use Component->GetEditComponent()  | |
| + | }  | ||
| + | </code>  | ||
| − | + | <code>  | |
| − | + | class cMouseMode {  | |
| − | activate,deactivate  | + | public :  | 
| − | child-functions ??  | + | 	// activate (=constructor),deactivate(=destructor)  | 
| − | + | 	// step(=draw gizmos, active child as param ???),  | |
| + | 	// abort(by rightclick, activates parent if set)  | ||
| + | 	// child-functions ??  | ||
| + | 	// hold SmartPtr to "cGizmo"s, and abort/selfkill on NotifyDestroy ?  | ||
| + | }  | ||
| + | </code>  | ||
| − | + | <code>  | |
| − | + | class cGizmo {  | |
| − | bool MouseOver(Vec3 o,Vec3 v);  | + | 	public:  | 
| − | // click+drag // TODO : Research : CEGUI click+drag handling  | + | 	bool MouseOver(Vec3 o,Vec3 v);  | 
| − | + | 	// click+drag // TODO : Research : CEGUI click+drag handling  | |
| + | 	// drawing, scaling from + -  | ||
| + | 	// move,scale,rot : smartptr to iEditable, selfkill on NotifyDestroy  | ||
| + | }  | ||
| + | </code>  | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | <code>  | |
| − | + | class cGrid {  | |
| − | + | 	public:  | |
| − | }  | + | 	// snapping support (iSnappable ??)  | 
| + | 	//   | ||
| + | }  | ||
| + | </code>  | ||
| − | + | == Diagrams ==  | |
| − | + | <graph>digraph G {   | |
| − | + | cGizmo -> cAxisGizmo -> { cMoveGizmo, cScaleGizmo };  | |
| − | + | cGizmo -> cRotateGizmo;  | |
| − | + | }</graph>  | |
| − | + | <graph>digraph G {   | |
| + | cFrameComponent -> cComponent;  | ||
| + | cGameComponent -> cComponent;  | ||
| + | cGameFrameComponent -> cFrameComponent;  | ||
| + | cEditFrameComponent -> {cFrameComponent,iMeshLike};  | ||
| + | cSelection -> iEditable;  | ||
| + | cComponentGroup -> cComponent;  | ||
| + | cEditComponentGroup -> {cComponentGroup,iEditable}  | ||
| + | }</graph>  | ||
| − | + | == use cases ==  | |
| − | + | === start first spaceship frame ===  | |
| − | + | * select create-frame tool  | |
| + | * click and drag from corner A (somewhere on grid) to corner B of the bottom side  | ||
| + | * release mouse and move up/down to place the top side  | ||
| + | * click to finish  | ||
| + | [[Image:sfz_create_frame.jpg]]  | ||
| + | === extrude or bevel single side ===  | ||
| + | * select extrude or bevel tool  | ||
| + | * click on side (not in selection) and drag to bevel/extrude this one side  | ||
| + | * if extrude  | ||
| + | ** release to finish  | ||
| + | * elseif bevel  | ||
| + | ** release starts scaling the extruded face  | ||
| + | ** click to finish  | ||
| + | [[Image:sfz_bevel_single.jpg]]  | ||
| + | === bevel/extrude selection ===  | ||
| + | * select pointer/selection tool  | ||
| + | * select face mode from mode tool (vertex/edge/face/component/group)  | ||
| + | * click + drag to select everything within rectangular area (rect-gizmo)  | ||
| + | * shift : add to selection, ctrl : remove from selection : change cursor  | ||
| + | * shift-click on single faces to add them to the selection  | ||
| + | * select extrude/bevel tool  | ||
| + | * click on side (in selection) and drag to bevel/extrude the selected faces together  | ||
| + | * if extrude  | ||
| + | ** release to finish  | ||
| + | * elseif bevel  | ||
| + | ** release starts scaling the extruded face  | ||
| + | ** click to finish  | ||
| + | [[Image:sfz_bevel_selection.jpg]]  | ||
| + | |||
| + | === docking 2 sides ===  | ||
| + | |||
| + | * user choses pinter/selection tool  | ||
| + | * user selects a single frame-side A  | ||
| + | * there is a tool-panel with 3 buttons : "dock","pickA","pickB"  | ||
| + | * pickA and pickB are of a special button class used for selecting faces  | ||
| + | * click on pickA opens popup with choices : "current Selection","list with named selections","pick by click",...  | ||
| + | * click on current selection chooses frame-side A and marks the "pickA" button as not-empty (change color?)  | ||
| + | * user selects a different single frame-side B on a different frame-component  | ||
| + | * same procedure as with pickA  | ||
| + | * click on "dock" button leaves the frame-side A in its place, and moves frame-side B to its position if possible (throw exception otherwise)  | ||
| + | * in data the two frames are now linked to each other, moving one also moves the other, and walking inside is possible (inner side has no hull)  | ||
| + | |||
| + | === quickdock ===  | ||
| + | |||
| + | * user pushes quickdock button (enters dock-mode which is a mousemode)  | ||
| + | * user clicks on faceA  | ||
| + | * while user moves mouse, a line is drawn from the center of faceA and faceA is highlited in some color  | ||
| + | * user clicks on faceB, and the dock is executed, dock-mode stays, so multiple docks can be made  | ||
| + | * user clicks on faceA2 ..  | ||
| + | * user clicks on faceB2 ..  | ||
| + | * ...  | ||
| + | * rightclick to stop/abort dock-mode  | ||
| + | |||
| + | |||
| + | |||
| + | == todo's ==  | ||
| + | |||
| + | * NameSpace for Editor ? (or just for whole project)  | ||
| + | * Research : Multiple Inheritance : Con-/Destructor Calling and Order  | ||
| + | * Research : Multiple Inheritance : automatic casting ??? or static_cast<Type>(ptr)  | ||
| + | * Research : Trac : auto-generate tickets from doxygen TODOs  | ||
| + | * Research : Doxygen syntax  | ||
| + | * Research : Exceptions   | ||
| + | * Research : Decorator : editor for cFrameComponent ?  | ||
| + | * Research : Python for Editor ?  | ||
| + | * Research : DesignPattern : Memento / State for Create/Destroy-Command ?  | ||
| + | * SkyBox-Texture using povray  | ||
| + | * Explosion-Animation using povray  | ||
| + | * Python integration   | ||
| + | ** editor  | ||
| + | ** hud  | ||
| + | ** story:dialog/messages,events(entersystem,grab,destroy,dock,countdown)treasure,rewards,enemies,missions  | ||
| + | * chain-of-responsibility pattern for mousemodes, to catch clicks/drags and keystrokes and return true if handled  | ||
| + | |||
| + | == notes/ideas ==  | ||
=== Intuitive Behavior ===  | === Intuitive Behavior ===  | ||
| Line 184: | Line 310: | ||
* macro : can be declared empty for release-compile  | * macro : can be declared empty for release-compile  | ||
* macro at beginning of function  | * macro at beginning of function  | ||
| − | * creates object, which runs out of scope as the function exits -  | + | * creates object, which runs out of scope as the function exits -> exception-safe  | 
| − | * pass   | + | * pass "path"("cBaseClass::MyMethod"),file,line to constructor  | 
* use (const char*)path pointer instead of string compare  | * use (const char*)path pointer instead of string compare  | ||
* profile : measure time from constructor to destructor  | * profile : measure time from constructor to destructor  | ||
| Line 209: | Line 335: | ||
=== Face/Edge/Vertex Indexing ===  | === Face/Edge/Vertex Indexing ===  | ||
| − | * prism based -  | + | * prism based -> use positive for top, negative for bottom  | 
* keep numbering if possible if only one half is changed  | * keep numbering if possible if only one half is changed  | ||
* smartptr-change notify usage ? (integrated listener pattern)  | * smartptr-change notify usage ? (integrated listener pattern)  | ||
| Line 215: | Line 341: | ||
=== Symetry ===  | === Symetry ===  | ||
| − | * operates on list  | + | * operates on list<component/sides/edges>:mutli-selection?, keeps binding, operator Source.  | 
| − | * mirror-plane + center-merger-plane gizmo :    | + | * mirror-plane + center-merger-plane gizmo :  <[]> <[I]>  | 
=== Editing ===  | === Editing ===  | ||
| Line 243: | Line 369: | ||
*types/smartpointers for vertex,edge,side  | *types/smartpointers for vertex,edge,side  | ||
*Selection managed as (named)list of those types  | *Selection managed as (named)list of those types  | ||
| − | *Selection depends on active   | + | *Selection depends on active "type" (vertex,edge,side,FrameComponent,group), no mixing  | 
*select gizmo (rectangle)  | *select gizmo (rectangle)  | ||
*Toggle select on intersect or only on complete containment  | *Toggle select on intersect or only on complete containment  | ||
| Line 250: | Line 376: | ||
*undo for selection  | *undo for selection  | ||
*group select : when group is already selected, click selects subgroup  | *group select : when group is already selected, click selects subgroup  | ||
| − | *map  | + | *map<smartptr<comp>,list<num>>  | 
=== Picking ===  | === Picking ===  | ||
| Line 260: | Line 386: | ||
=== Tools ===  | === Tools ===  | ||
| − | *ToolPanel = view, Tool = model(singleton) -  | + | *ToolPanel = view, Tool = model(singleton) -> model/view seperation, change-listener  | 
| − | *Tool-  | + | *Tool->CreatePanel()  | 
*Python Support ??  | *Python Support ??  | ||
| − | *Tools can   | + | *Tools can "pick" current selection, named selection, groups, or pick-by-click    | 
| + | * camera rotation mode : around current selection, world center, around self(firstperson mode)  | ||
* Grid Move Gizmo = Axis at left-top  | * Grid Move Gizmo = Axis at left-top  | ||
* Grid Centered on Origin, Center of Current Selection, or fixed point  | * Grid Centered on Origin, Center of Current Selection, or fixed point  | ||
* Grid x,y,z,off (toggle bindable to key)  | * Grid x,y,z,off (toggle bindable to key)  | ||
* Named Selections (depends on current mode (vertex,edge,side,FrameComponent,group)) + Select/Unselect/Show/Hide/Delete  | * Named Selections (depends on current mode (vertex,edge,side,FrameComponent,group)) + Select/Unselect/Show/Hide/Delete  | ||
| − | * Mode Selection (vertex,edge,side,FrameComponent,group)  | + | * Mode Selection (vertex,edge,side,FrameComponent,group) [[Image:sfz_mode.jpg]]  | 
* Tool Selection (Select,Move,Scale,Rotate,Extrude,Bevel,SpinExtrude,SpinBevel)  | * Tool Selection (Select,Move,Scale,Rotate,Extrude,Bevel,SpinExtrude,SpinBevel)  | ||
* Snap (Grid,Vertex,Edge,Face)  | * Snap (Grid,Vertex,Edge,Face)  | ||
| Line 276: | Line 403: | ||
* Hierarchy-List (also for popup)  | * Hierarchy-List (also for popup)  | ||
* Change Parent (opens hierarchy-list popup)  | * Change Parent (opens hierarchy-list popup)  | ||
| − | * Later : Change Type (popup : for compatible types, eg titanframe -  | + | * Later : Change Type (popup : for compatible types, eg titanframe -> steelframe ??)  | 
* Later : Change Side (point,line,3up,3down,square,penta,[x]:popup)  | * Later : Change Side (point,line,3up,3down,square,penta,[x]:popup)  | ||
| − | 	only for top/bottom, autoconvert if top/bottom   | + | 	only for top/bottom, autoconvert if top/bottom <= 4  | 
* Later : Toggle select on intersect or only on complete containment  | * Later : Toggle select on intersect or only on complete containment  | ||
* Later : QuickCut/Slice (FrameComponent, : DrawLine Gizmo  | * Later : QuickCut/Slice (FrameComponent, : DrawLine Gizmo  | ||
| Line 298: | Line 425: | ||
*TODO : Research : CEGUI  | *TODO : Research : CEGUI  | ||
| − | *Tool/Mode/Gizmo can activate   | + | *Tool/Mode/Gizmo can activate "MouseMode", abort on esc,rightclick  | 
and when another MouseMode is activated  | and when another MouseMode is activated  | ||
| Line 312: | Line 439: | ||
	and enables cheating (ultra compact, multi-dimensional cargo bays)  | 	and enables cheating (ultra compact, multi-dimensional cargo bays)  | ||
| − | + | <pre><nowiki>  | |
    ---  |     ---  | ||
   /\X/\  |    /\X/\  | ||
  /  -  \  |   /  -  \  | ||
  -------  |   -------  | ||
| − | + |   </nowiki></pre>  | |
| Line 357: | Line 484: | ||
* system (starsystem) contains entities  | * system (starsystem) contains entities  | ||
* entity has course, pos+vel or pos+orbit(center,elliptic-params)  | * entity has course, pos+vel or pos+orbit(center,elliptic-params)  | ||
| + | |||
| + | ----  | ||
Latest revision as of 16:48, 9 January 2011
(mostly obsolete, will be coded mainly in lua now, some ideas might be used though)
>= OLM =
- ObjectOriented-Lowpoly-Modeller
 - Prism Based -> enhanced Interior Detection and Mesh-Management
 
Contents
- 1 Headers
 - 2 Diagrams
 - 3 use cases
 - 4 todo's
 - 5 notes/ideas
- 5.1 Intuitive Behavior
 - 5.2 StackTracer/Profile
 - 5.3 Custom-Assert
 - 5.4 Linking
 - 5.5 Locking
 - 5.6 Face/Edge/Vertex Indexing
 - 5.7 Symetry
 - 5.8 Editing
 - 5.9 Move,Scale,Rotate
 - 5.10 Creation
 - 5.11 Selection
 - 5.12 Picking
 - 5.13 Tools
 - 5.14 Gizmos
 - 5.15 Click / Drag Handling
 - 5.16 Spawning/ObjectCreation
 - 5.17 Inclusion/Intersection Warning
 - 5.18 Blinking/Signal lights
 - 5.19 Sensors
 - 5.20 ComponentTypes
 - 5.21 SampleComponents
 - 5.22 Naming Scheme
 
 
Headers
<code> class iSmartPointable<class _T> { public: void RegisterSmartPtr (SmartPtr<_T>* p); void UnregisterSmartPtr (SmartPtr<_T>* p); SmartPtr<_T>* GetSmartPtr (iSmartPtrListener* listener);
protected: std::List<SmartPtr<_T>*> smartPointers; iSmartPointable(); // empty, protected (must inherit) ~iSmartPointable(); // calls NotifyDestroy() of all smartPointers void NotifySmartPtrChange(const int code); // calls NotifyChange() of all smartPointers (idea) }
class iSmartPtrListener<class _T> { public : virtual void NotifySmartPtrDestroy (SmartPtr<_T>* sp); virtual void NotifySmartPtrChange (SmartPtr<_T>* sp,const int code); }
class SmartPtr<class _T> { public : SmartPtr (_T* target=0,iSmartPtrListener<_T>* listener=0); // target=0 possible !!! (register) ~SmartPtr (); // (unregister) void SetTarget (_T* target) // unregister old + register new void NotifyDestroy (); // calls listener->NotifyDestroy() _T& operator = (_T* cmp) // test for equality _T& operator = (SmartPtr<_T> cmp) // test for equality _T& operator * () // todo : lookup syntax for (*smartptr), something like (int dummy) _T& operator -> ()
private : _T* target; // _T must be iSmartPointable, can be 0 iSmartPtrListener* listener; // can be 0 } </code>
<code> class iEditable { public : virtual void Move (Vec3 v); virtual void Scale (Vec3 v,Vec3 o = gVec3Zero); // might not operate on vertices ! virtual void Rotate (Vec3 v,Vec3 o = gVec3Zero); virtual void Rotate (Quaternion q,Vec3 o = gVec3Zero); // void transform(matrix m) ? might not operate on vertices (cockpit-component is iEditable) } </code>
<code> class iMeshLike : public iEditable { public : virtual Vec3& EditVertex (const int i); // throws exception if index out of bounds virtual int CountVertices (); Vec3 GetBoundsMin (); Vec3 GetBoundsMax (); Vec3 GetBoundsCenter (); Vec3 GetPivot ();
// todo : readonly lists or complete management in this class ? // usecase : ship-frame(readwrite) cockpit(readonly:just one dockable side, and move/rotatable for complete object) list GetLinkedSides(SideNum); list GetLinkedVertices(VertexNum); list GetLinkedEdges(EdgeNum); list GetSideVertices(SideNum); list GetEdgeVertices(EdgeNum); vertex,side,edge enumeration and access editable functions position+rotation access -> coordinate conversion + align rotation. flags for lock vertices, lock pos/rot... cockpit is model with one designated side for docking, vertices cannot be changed, but position+rotation change is possible framecomponent does not need to use rotation, as the vertices are usualle freely movable when docked to cockpit, and moving the docked side, try to rotate/move the cockpit as closely as possible, then readjust vertices also otpional "lock form/vertices" for completed frame components (only rotate/position) -> behave similar to cockpit // visual feedback(side/edge/face hilighting, gizmos...) implemented in this class ?? } </code>
<code>
class cComponent {
	public:
	SmartPtr<cComponent> parent; // =0 for top, frame:group,maschine:frame,...
	position,rotation
	GetBounds()
	GenBluePrint(tex,axis,offset,scale,colors)
	Cast2Group()
	Cast2Frame()
	ComponentType*	type;
	// emissions for sensors....
	// blueprint status display : functionality and damage
	NotifyDamage(); // Section (groupname) has been hit..
	GetDescription();
	// also baseclass for inner-maschinery etc...
	// coordinate translation ! (rotation)
	//intersection,inclusion-calc
}
</code>
<code> class cFrameComponent : public iMeshLike { public: list<Vec3> top; list<Vec3> bot; int flags; EditComponent GetEditComponent (); // null or overridden } </code>
<code>
class cModuleComponent : public iMeshLike { 
	public:
	list<list<Vec3>>	sides;
	// throws exceptions on illegal edit
	// cockpit, solarpanel...
	// ??? iMeshLike -> iEditable outside editor (deform from hit ??)
}
</code>
<code> class cComponentType { public: // SteelFrame,TitanFrame,Cockpit... } </code>
<code> class cEditComponent { public: // lists for selected vertices,edges,sides and whole FrameComponent } </code>
<code> class cSelection : iEditable { public: // Selection != Group, as selection can be mutliple vertices/faces/lines... } </code>
<code>
class cComponentGroup {
	public:
	std::string	name;
	std::list<Component> elements;
}
</code>
<code> class EditComponentGroup { public: // type of elements = EditComponent, use Component->GetEditComponent() } </code>
<code>
class cMouseMode {
public :
	// activate (=constructor),deactivate(=destructor)
	// step(=draw gizmos, active child as param ???),
	// abort(by rightclick, activates parent if set)
	// child-functions ??
	// hold SmartPtr to "cGizmo"s, and abort/selfkill on NotifyDestroy ?
}
</code>
<code>
class cGizmo {
	public:
	bool MouseOver(Vec3 o,Vec3 v);
	// click+drag // TODO : Research : CEGUI click+drag handling
	// drawing, scaling from + -
	// move,scale,rot : smartptr to iEditable, selfkill on NotifyDestroy
}
</code>
<code>
class cGrid {
	public:
	// snapping support (iSnappable ??)
	// 
}
</code>
Diagrams
<graph>digraph G { cGizmo -> cAxisGizmo -> { cMoveGizmo, cScaleGizmo }; cGizmo -> cRotateGizmo; }</graph>
<graph>digraph G { cFrameComponent -> cComponent; cGameComponent -> cComponent; cGameFrameComponent -> cFrameComponent; cEditFrameComponent -> {cFrameComponent,iMeshLike}; cSelection -> iEditable; cComponentGroup -> cComponent; cEditComponentGroup -> {cComponentGroup,iEditable} }</graph>
use cases
start first spaceship frame
- select create-frame tool
 - click and drag from corner A (somewhere on grid) to corner B of the bottom side
 - release mouse and move up/down to place the top side
 - click to finish
 
extrude or bevel single side
- select extrude or bevel tool
 - click on side (not in selection) and drag to bevel/extrude this one side
 -  if extrude
- release to finish
 
 -  elseif bevel
- release starts scaling the extruded face
 - click to finish
 
 
bevel/extrude selection
- select pointer/selection tool
 - select face mode from mode tool (vertex/edge/face/component/group)
 - click + drag to select everything within rectangular area (rect-gizmo)
 - shift : add to selection, ctrl : remove from selection : change cursor
 - shift-click on single faces to add them to the selection
 - select extrude/bevel tool
 - click on side (in selection) and drag to bevel/extrude the selected faces together
 -  if extrude
- release to finish
 
 -  elseif bevel
- release starts scaling the extruded face
 - click to finish
 
 
docking 2 sides
- user choses pinter/selection tool
 - user selects a single frame-side A
 - there is a tool-panel with 3 buttons : "dock","pickA","pickB"
 - pickA and pickB are of a special button class used for selecting faces
 - click on pickA opens popup with choices : "current Selection","list with named selections","pick by click",...
 - click on current selection chooses frame-side A and marks the "pickA" button as not-empty (change color?)
 - user selects a different single frame-side B on a different frame-component
 - same procedure as with pickA
 - click on "dock" button leaves the frame-side A in its place, and moves frame-side B to its position if possible (throw exception otherwise)
 - in data the two frames are now linked to each other, moving one also moves the other, and walking inside is possible (inner side has no hull)
 
quickdock
- user pushes quickdock button (enters dock-mode which is a mousemode)
 - user clicks on faceA
 - while user moves mouse, a line is drawn from the center of faceA and faceA is highlited in some color
 - user clicks on faceB, and the dock is executed, dock-mode stays, so multiple docks can be made
 - user clicks on faceA2 ..
 - user clicks on faceB2 ..
 - ...
 - rightclick to stop/abort dock-mode
 
todo's
- NameSpace for Editor ? (or just for whole project)
 - Research : Multiple Inheritance : Con-/Destructor Calling and Order
 - Research : Multiple Inheritance : automatic casting ??? or static_cast<Type>(ptr)
 - Research : Trac : auto-generate tickets from doxygen TODOs
 - Research : Doxygen syntax
 - Research : Exceptions
 - Research : Decorator : editor for cFrameComponent ?
 - Research : Python for Editor ?
 - Research : DesignPattern : Memento / State for Create/Destroy-Command ?
 - SkyBox-Texture using povray
 - Explosion-Animation using povray
 -  Python integration 
- editor
 - hud
 - story:dialog/messages,events(entersystem,grab,destroy,dock,countdown)treasure,rewards,enemies,missions
 
 - chain-of-responsibility pattern for mousemodes, to catch clicks/drags and keystrokes and return true if handled
 
notes/ideas
Intuitive Behavior
- esc,rightclick : cancel mousemode
 - backspace=back_to_parent, return=show_detail
 - remove(delete) : kill/remove/collapse selected
 
StackTracer/Profile
- see sfz-wiki : std:uncaught_exception()
 - macro : can be declared empty for release-compile
 - macro at beginning of function
 - creates object, which runs out of scope as the function exits -> exception-safe
 - pass "path"("cBaseClass::MyMethod"),file,line to constructor
 - use (const char*)path pointer instead of string compare
 - profile : measure time from constructor to destructor
 
Custom-Assert
- keep gui intact if possible
 - write report to file
 - print stacktrace
 - offer options : ignore,abort,debug,throw-exception
 
Linking
- Link Sides from different components
 - throw exception when trying to move/scale/rotate link when locked
 - throw exception when trying to change form of link when locked
 
Locking
- lock form(edge-count,connections,NOT SIZE/POS), size(rotate allowed ??), position
 - beware of linking !
 
Face/Edge/Vertex Indexing
- prism based -> use positive for top, negative for bottom
 - keep numbering if possible if only one half is changed
 - smartptr-change notify usage ? (integrated listener pattern)
 
Symetry
- operates on list<component/sides/edges>:mutli-selection?, keeps binding, operator Source.
 - mirror-plane + center-merger-plane gizmo : <[]> <[I]>
 
Editing
- All Operations use the Command Pattern, to support Undo/Redo
 - Uses Mnemonic/Inner State Pattern for Create/Destroy
 - Python Support ??
 - Commands bindable to Buttons, Keys/KeyCombos, MenuItems, Right-Click Menu....
 
Move,Scale,Rotate
- when Tool is active, show the apropriate gizmo in scene
 - gizmo acts on Current Selection (iEditable)
 - gizmo gives visual MouseOver feedback
 - support snapping
 
Creation
- CreateFrameComponent : Activates a Create-Mode :
 - click(first corner) + drag(2d base) + click(3d)
 - gizmo gives visual feedback during creation
 - support snapping
 
Selection
- types/smartpointers for vertex,edge,side
 - Selection managed as (named)list of those types
 - Selection depends on active "type" (vertex,edge,side,FrameComponent,group), no mixing
 - select gizmo (rectangle)
 - Toggle select on intersect or only on complete containment
 - manual selection with shift(add) and control(remove)
 - when selection from list, and last selection was manually altered, save last manual selection as named
 - undo for selection
 - group select : when group is already selected, click selects subgroup
 - map<smartptr<comp>,list<num>>
 
Picking
in popup :
- current selection,
 - named selection,
 - hierarchy list (groups)
 - pick-by-click (current mode : vertex,edge,side,FrameComponent,group)
 
Tools
- ToolPanel = view, Tool = model(singleton) -> model/view seperation, change-listener
 - Tool->CreatePanel()
 - Python Support ??
 - Tools can "pick" current selection, named selection, groups, or pick-by-click
 
- camera rotation mode : around current selection, world center, around self(firstperson mode)
 - Grid Move Gizmo = Axis at left-top
 - Grid Centered on Origin, Center of Current Selection, or fixed point
 - Grid x,y,z,off (toggle bindable to key)
 - Named Selections (depends on current mode (vertex,edge,side,FrameComponent,group)) + Select/Unselect/Show/Hide/Delete
 -  Mode Selection (vertex,edge,side,FrameComponent,group) Error creating thumbnail: Unable to save thumbnail to destination
 - Tool Selection (Select,Move,Scale,Rotate,Extrude,Bevel,SpinExtrude,SpinBevel)
 - Snap (Grid,Vertex,Edge,Face)
 - AngleSnap (edit+on/off button + buttons for 20 30 40 45 60 90)
 - Name+Group / Ungroup
 - Hierarchy-List (also for popup)
 - Change Parent (opens hierarchy-list popup)
 - Later : Change Type (popup : for compatible types, eg titanframe -> steelframe ??)
 - Later : Change Side (point,line,3up,3down,square,penta,[x]:popup)
 
only for top/bottom, autoconvert if top/bottom <= 4
- Later : Toggle select on intersect or only on complete containment
 - Later : QuickCut/Slice (FrameComponent, : DrawLine Gizmo
 - Later : Create Adapter : pick operand a,b
 - Later : ExtrudeAroundEdge,TurnAroundEdge (pick edge + turn selection)
 - Later : SoftSelection (falloff:distance/adjactance,falloff:linear,cubic,curve,falloffdist)
 - Later : Dock : move 2 sides together and link them, pick base(not moved) and operand (modifyed)
 - Later : Constraints/Links + LockSize (link 2 sides of different FrameComponents, only move, not scale group)
 - Later : Prism-Based Subdivide (height/width)
 - Later : Hide/Show Selection/All
 
Gizmos
- scalable with +/-
 - mouseovereffekt, areas : axis,area-between
 
Click / Drag Handling
- TODO : Research : CEGUI
 
- Tool/Mode/Gizmo can activate "MouseMode", abort on esc,rightclick
 
and when another MouseMode is activated
Spawning/ObjectCreation
- MouseMode
 - Frame/Cockpit :
- click on side : extrude/bevel
 - click on empty : create in space/ on grid
 
 
Inclusion/Intersection Warning
- not possible for space ships, breaks interior-definition,
 
and enables cheating (ultra compact, multi-dimensional cargo bays)
<pre><nowiki>
--- /\X/\ / - \ ------- </nowiki></pre>
Blinking/Signal lights
- position on hull, can have limied offset
 - choose color, frequency and offset
 
Sensors
- Heat/Temperature, Radioactivity, Electricity, Mass, Radar(metal), Bio
 - spectrum analyzer : distinct materials
 - active scanning (radar, detailed materials, freight)
 - colors can be customized
 - hud element for active scanning : modus (off, manual ping, fade display, ping interval)
 -  hud element for radar : 2 half-spheres (front and back) or single full sphere
- FOF-colors customizable, lines to center : distance...
 - alternate : 2d-circle with orthogonal-lines indicating height
 
 
ComponentTypes
- implement constraints by inheritance or decorator or callback...
 -  factory for components ?? 
- (could be used to convert component-type if neccessary : steel-titan-frame)
 - editable restraints
 
 
SampleComponents
- Frame (different materials, eg steel,titan,...)
 - Cockpit/Bridge (different models)
 - Scalable Thruster/Engine
 - Scalable Solar Panel (rotatable?)
 - Mountable Thruster ( mount on wing, like jumbo-jet, can mount missile/rocket-launcher instead)
 
Naming Scheme
- entity : ship,cargo-box,star,planet...
 - entity has components
 - system (starsystem) contains entities
 - entity has course, pos+vel or pos+orbit(center,elliptic-params)