Transform.cpp
Go to the documentation of this file.
1 #include "Transform.hpp"
2 
3 #include "../Defs.hpp"
4 
5 namespace iv
6 {
7 
9  OneChildElem< SlotChild >( inst ),
10  SlotChild( this ),
11  cm( inst, this, "Transform", ClientMarker::Status() ),
12  attr_position( &this->cm, float3( 0, 0, 0 ) ),
13  attr_rotation( &this->cm, floatQuat() ),
14  attr_scale( &this->cm, float3( 1, 1, 1 ) ),
15  attr_deformation( &this->cm, float4x4( 1 ) ),
16  attr_outerAnchor( &this->cm, float3( 0.5f, 0.5f, 0.5f ) ),
17  attr_innerAnchor( &this->cm, float3( 0.5f, 0.5f, 0.5f ) ),
18  attr_propagateSize( &this->cm, false ),
19  outer_transform_refresh( false ),
20  inner_transform_refresh( false )
21 {
23 }
24 
26 {
27  static iv::TableId DebugTable = TableId::create( "Transform" );
28  auto row = view->Table( DebugTable ).Row( this );
29 
30  row.Column( "position", this->attr_position.Get() );
31  row.Column( "rotation", this->attr_rotation.Get() );
32  row.Column( "scale", this->attr_scale.Get() );
33  row.Column( "deformation", this->attr_deformation.Get() );
34 
35  row.Column( "outerAnchor", this->attr_outerAnchor.Get() );
36  row.Column( "innerAnchor", this->attr_innerAnchor.Get() );
37 
38  row.Column( "propagateSize", this->attr_propagateSize.Get() );
39 }
40 
42 {
43  this->cm.log( SRC_INFO, Defs::Log::ElementFirstPass, "First pass." );
44 
45  // first pass on child and refresh preferred size
46  if( this->child.Get() )
47  {
48  if( this->child.dirty() || this->expectedSize.dirty() || this->attr_propagateSize.dirty() )
49  {
50  this->expectedSize.clear_dirty();
51 
52  if( this->attr_propagateSize.Get() )
53  this->child.Get()->expectedSize.Set( this->expectedSize.Get() );
54  else
55  this->child.Get()->expectedSize.Set( float3( std::numeric_limits< float >::infinity(), std::numeric_limits< float >::infinity(), std::numeric_limits< float >::infinity() ) );
56  }
57 
58  this->child.Get()->elem()->first_pass( er );
59 
60  if( this->child.clear_dirty() || this->attr_propagateSize.clear_dirty() || this->child.Get()->preferredSize.clear_dirty() || this->attr_deformation.clear_dirty() || this->attr_innerAnchor.clear_dirty() )
61  {
62  this->cm.log( SRC_INFO, Defs::Log::ElementFirstPass, "Refresh preferred_size, set inner_transform_refresh." );
63 
64  if( this->attr_propagateSize.Get() )
65  {
67  this->preferredSize.Set( this->child.Get()->preferredSize.Get() );
68  }
69  else
70  {
71  this->preferredSize.Set( float3( 0, 0, 0 ) );
72  }
73 
74  this->inner_transform_refresh = true;
75  }
76  }
77  else
78  {
79  if( this->child.dirty() )
80  {
81  this->cm.log( SRC_INFO, Defs::Log::ElementFirstPass, "Refresh preferred_size." );
82  this->preferredSize.Set( float3( 0, 0, 0 ) );
83  }
84  }
85 
86  if( this->child.Get() )
87  {
88  if( this->attr_position.clear_dirty() || this->attr_rotation.clear_dirty() || this->attr_scale.clear_dirty() || this->attr_outerAnchor.clear_dirty() )
89  {
90  this->cm.log( SRC_INFO, Defs::Log::ElementFirstPass, "Set outer_transform_refresh." );
91 
92 
93  //
94  this->outer_transform_refresh = true;
95  }
96 
97  if( this->child.dirty() || this->inner_transform_refresh || this->outer_transform_refresh || this->modelTransform.dirty() || this->size.dirty() || this->scissor.dirty() )
98  {
99  this->cm.log( SRC_INFO, Defs::Log::ElementFirstPass, "Queue second pass." );
100  er->QueueSecondPass( this );
101  }
102  }
103 }
104 
106 {
107  this->cm.log( SRC_INFO, Defs::Log::ElementSecondPass, "Second pass." );
108 
109  // delay any refreshes if there is no child
110  if( !this->child.Get() )
111  return;
112 
113  bool refresh = false;
114 
115  // inner transform
116  if( this->inner_transform_refresh || this->size.dirty() )
117  {
118  this->cm.log( SRC_INFO, Defs::Log::ElementSecondPass, "Refresh inner transform." );
119 
120  //
121  this->inner_transform_refresh = false;
122 
123  //
124  refresh = true;
125 
126  //
127  if( this->attr_propagateSize.Get() )
128  this->child.Get()->size.Set( this->size.Get() );
129  else
130  this->child.Get()->size.Set( this->child.Get()->preferredSize.Get() );
131 
132  this->inner_transform = glm::translate( float4x4( 1 ), float3() - this->child.Get()->size.Get() * this->attr_innerAnchor.Get() ) * this->attr_deformation.Get();
133  }
134 
135  // outer transform
136  if( this->outer_transform_refresh || this->size.clear_dirty() )
137  {
138  this->outer_transform_refresh = false;
139 
140  this->cm.log( SRC_INFO, Defs::Log::ElementSecondPass, "Refresh outer transform." );
141 
142  //
143  refresh = true;
144 
145  //
146  this->outer_transform = glm::translate( float4x4( 1 ), this->size.Get() * this->attr_outerAnchor.Get() )
147  * glm::translate( float4x4( 1 ), this->attr_position.Get() )
148  * glm::mat4_cast( this->attr_rotation.Get() )
149  * glm::scale( float4x4( 1 ), this->attr_scale.Get() );
150  }
151 
152  // refresh
153  if( refresh || this->child.clear_dirty() || this->modelTransform.clear_dirty() || this->scissor.clear_dirty() )
154  {
155  this->cm.log( SRC_INFO, Defs::Log::ElementSecondPass, "Apply transforms." );
156 
157  er->Notify_SecondPass_Refresh( this );
158 
159  this->child.Get()->elem()->modelTransform.Set( this->modelTransform.Get() * this->outer_transform * this->inner_transform );
160  this->child.Get()->elem()->scissor.Set( this->scissor.Get() );
161  this->child.Get()->elem()->second_pass( er );
162  }
163 }
164 
166 {
167  this->attr_position.Set( val );
168  return this;
169 }
170 
172 {
173  this->attr_rotation.Set( val );
174  return this;
175 }
176 
178 {
179  this->attr_scale.Set( val );
180  return this;
181 }
182 
184 {
185  this->attr_deformation.Set( val );
186  return this;
187 }
188 
190 {
191  this->attr_outerAnchor.Set( val );
192  return this;
193 }
194 
196 {
197  this->attr_innerAnchor.Set( val );
198  return this;
199 }
200 
202 {
203  this->attr_propagateSize.Set( val );
204  return this;
205 }
206 
207 }