Elem.cpp
Go to the documentation of this file.
1 #include "Elem.hpp"
2 #include "Camera.hpp"
3 #include "ElementSystem.hpp"
5 
6 namespace iv
7 {
8 
9 Elem::Elem( Instance * inst ) :
10  InputNode( inst ),
11  cm( inst, this, "Elem", ClientMarker::Status() ),
12  attr_enabled( &this->cm, true ),
13  modelTransform( &this->cm, float4x4( 1 ) ),
14  scissor( &this->cm ),
15  inst( inst ),
16  _first_pass_frame_id( 0 ),
17  _second_pass_frame_id( 0 ),
18  _quiet( false ),
19  _elem_parent( nullptr )
20 {
21  this->cm.inherits( this->InputNode::cm );
22 
23  auto es = this->instance()->getSystem< ElementSystem >();
24  if( es )
25  es->elem_register( this );
26 }
27 
29 {
30  if( this->_elem_parent )
31  this->_elem_parent->elem_childDisconnect( this );
32 
33  auto es = this->instance()->getSystem< ElementSystem >();
34  if( es )
35  es->elem_unregister( this );
36 }
37 
38 
40 {
41  return this->_elem_parent;
42 }
43 
45 {
46  if( auto parent = this->elem_getParent() )
47  return parent->elem_getRoot();
48  else
49  return nullptr;
50 }
51 
52 void Elem::elem_setParent( Elem * parent )
53 {
54  this->_elem_parent = parent;
55 }
56 
58 {
59  return this->inst;
60 }
61 
63 {
64  static iv::TableId DebugTable = TableId::create( "Elem" );
65 
66  auto row = view->Table( DebugTable ).Row( this );
67 
68  row.Column( "enabled", this->attr_enabled.Get() );
69  row.Column( "modelTransform", this->modelTransform.Get() );
70  row.Column( "scissor", this->scissor.Get().enabled );
71 }
72 
74 {
75  if( this->attr_enabled.dirty() )
76  {
77  this->attr_enabled.clear_dirty();
78  this->InputNode::inputEnabled( this->attr_enabled.Get() );
79  }
80 
81  if( !this->attr_enabled.Get() )
82  return;
83 
84  this->_first_pass_frame_id = this->instance()->frame_id();
85 
86  this->first_pass_impl( er );
87 }
88 
90 {
91  if( !this->attr_enabled.Get() )
92  return;
93 
94  if( this->instance()->frame_id() == this->second_pass_frame_id() )
95  this->cm.warning( SRC_INFO, "Element already had second pass called on itself this frame (order of second passes is wrong)." );
96 
97  this->_second_pass_frame_id = this->instance()->frame_id();
98 
99  er->DequeueSecondPass( this );
100 
101  this->second_pass_impl( er );
102 }
103 
105 {
106  // camera check
107  Camera * camera = this->elem_getRoot();
108  if( !camera )
109  return float3( 0, 0, 0 );
110 
111  // transform
112  float4x4 model = this->modelTransform.Get();
113  return camera->FromLocalSpaceToViewportSpace( model, local_space );
114 }
115 
117 {
118  // camera check
119  Camera * camera = this->elem_getRoot();
120  if( !camera )
121  return float3( 0, 0, 0 );
122 
123  // transform
124  float4x4 model = this->modelTransform.Get();
125  return camera->FromViewportSpaceToLocalSpace( model, screen_space );
126 }
127 
129 {
130  // camera check
131  Camera * camera = this->elem_getRoot();
132  if( !camera )
133  return float2( 0, 0 );
134 
135  // transform
136  float4x4 model = this->modelTransform.Get();
137  return camera->FromViewportPlaneToLocalPlane( model, screen_space );
138 }
139 
140 Elem * Elem::enabled( bool val )
141 {
142  this->attr_enabled.Set( val );
143  return this;
144 }
145 
147 {
148  return this->_first_pass_frame_id;
149 }
150 
152 {
153  return this->_second_pass_frame_id;
154 }
155 
156 void Elem::quiet( bool val )
157 {
158  this->_quiet = val;
159 }
160 
161 bool Elem::quiet() const
162 {
163  return this->_quiet;
164 }
165 
167 {
168  // disconnect node from previous parent
169  if( node->input_getParent() )
170  node->input_getParent()->input_childDisconnect( node );
171 
172  //
173  this->_input_children.push_back( node );
174  node->input_setParent( this );
175 }
176 
178 {
179  this->input_childDisconnect( node );
180 }
181 
183 {
184  for( size_t i = 0; i < this->_input_children.size(); i++ )
185  if( this->_input_children[ i ] == node )
186  {
187  this->_input_children[ i ]->input_setParent( nullptr );
188  this->_input_children.erase( this->_input_children.begin() + i );
189  break;
190  }
191 }
192 
193 void Elem::input_eachChild( std::function< void( InputNode * ) > const & f )
194 {
195  for( auto it = this->_input_children.rbegin(); it != this->_input_children.rend(); ++it )
196  f( *it );
197 }
198 
199 //=================================================
201  cm( elem->instance(), this, "Pickable" ),
202  _elem( elem )
203 {
204 }
205 
207 {
208  return this->_elem;
209 }
210 
211 Elem const * Pickable::elem() const
212 {
213  return this->_elem;
214 }
215 
216 }