Changed view frustum culling to ignore mesh extents and instead use actor extents.
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / geometry-impl.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/rendering/geometry-impl.h> // Dali::Internal::Geometry
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/object/type-registry.h>
23
24 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
25 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
26 #include <dali/internal/update/common/double-buffered-property.h>
27 #include <dali/internal/update/manager/update-manager.h>
28
29 namespace Dali
30 {
31 namespace Internal
32 {
33
34 namespace
35 {
36
37 /**
38  *            |name                    |type     |writable|animatable|constraint-input|enum for index-checking|
39  */
40 DALI_PROPERTY_TABLE_BEGIN
41 DALI_PROPERTY( "geometry-type",         STRING,   true, false,  true, Dali::Geometry::Property::GEOMETRY_TYPE )
42 DALI_PROPERTY( "geometry-center",       VECTOR3,  true, true,   true, Dali::Geometry::Property::GEOMETRY_CENTER )
43 DALI_PROPERTY( "requires-depth-test",   BOOLEAN,  true, false,  true, Dali::Geometry::Property::REQUIRES_DEPTH_TEST )
44 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
45
46 const ObjectImplHelper<DEFAULT_PROPERTY_COUNT> GEOMETRY_IMPL = { DEFAULT_PROPERTY_DETAILS };
47
48 BaseHandle Create()
49 {
50   return Dali::Geometry::New();
51 }
52
53 TypeRegistration mType( typeid( Dali::Geometry ), typeid( Dali::Handle ), Create );
54
55 } // unnamed namespace
56
57 GeometryPtr Geometry::New()
58 {
59   GeometryPtr geometry( new Geometry() );
60   geometry->Initialize();
61   return geometry;
62 }
63
64 std::size_t Geometry::AddVertexBuffer( PropertyBuffer& vertexBuffer )
65 {
66   PropertyBufferConnector connector;
67   connector.Set( vertexBuffer, OnStage() );
68   mVertexBufferConnectors.push_back( connector );
69
70   const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = static_cast<const SceneGraph::PropertyBuffer&>( *vertexBuffer.GetSceneObject() );
71
72   SceneGraph::AddVertexBufferMessage( GetEventThreadServices(), *mSceneObject, sceneGraphPropertyBuffer );
73
74   return mVertexBufferConnectors.size() - 1u;
75 }
76
77 std::size_t Geometry::GetNumberOfVertexBuffers() const
78 {
79   return mVertexBufferConnectors.size();
80 }
81
82 void Geometry::RemoveVertexBuffer( std::size_t index )
83 {
84   const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = static_cast<const SceneGraph::PropertyBuffer&>( *(mVertexBufferConnectors[index].Get()->GetSceneObject()) );
85   SceneGraph::RemoveVertexBufferMessage( GetEventThreadServices(), *mSceneObject, sceneGraphPropertyBuffer );
86
87   mVertexBufferConnectors.erase( mVertexBufferConnectors.begin() + index );
88 }
89
90 void Geometry::SetIndexBuffer( PropertyBuffer& indexBuffer )
91 {
92   mIndexBufferConnector.Set( indexBuffer, OnStage() );
93
94   const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = dynamic_cast<const SceneGraph::PropertyBuffer&>( *indexBuffer.GetSceneObject() );
95
96   SceneGraph::SetIndexBufferMessage( GetEventThreadServices(), *mSceneObject, sceneGraphPropertyBuffer );
97 }
98
99 void Geometry::SetGeometryType( Dali::Geometry::GeometryType geometryType )
100 {
101   if( NULL != mSceneObject )
102   {
103     SceneGraph::DoubleBufferedPropertyMessage<int>::Send(
104       GetEventThreadServices(),
105       mSceneObject,
106       &mSceneObject->mGeometryType,
107       &SceneGraph::DoubleBufferedProperty<int>::Set,
108       static_cast<int>(geometryType) );
109   }
110 }
111
112 Dali::Geometry::GeometryType Geometry::GetGeometryType() const
113 {
114   return mSceneObject->GetGeometryType(GetEventThreadServices().GetEventBufferIndex());
115 }
116
117 void Geometry::SetRequiresDepthTesting( bool requiresDepthTest )
118 {
119   if( NULL != mSceneObject )
120   {
121     SceneGraph::DoubleBufferedPropertyMessage<bool>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mRequiresDepthTest, &SceneGraph::DoubleBufferedProperty<bool>::Set, static_cast<int>(requiresDepthTest) );
122   }
123 }
124
125 bool Geometry::GetRequiresDepthTesting() const
126 {
127   if( mSceneObject )
128   {
129     // mSceneObject is being used in a separate thread; copy the value from the previous update
130     return mSceneObject->GetRequiresDepthTesting(GetEventThreadServices().GetEventBufferIndex());
131   }
132   return false;
133 }
134
135 const SceneGraph::Geometry* Geometry::GetGeometrySceneObject() const
136 {
137   return mSceneObject;
138 }
139
140 unsigned int Geometry::GetDefaultPropertyCount() const
141 {
142   return GEOMETRY_IMPL.GetDefaultPropertyCount();
143 }
144
145 void Geometry::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
146 {
147   GEOMETRY_IMPL.GetDefaultPropertyIndices( indices );
148 }
149
150 const char* Geometry::GetDefaultPropertyName(Property::Index index) const
151 {
152   return GEOMETRY_IMPL.GetDefaultPropertyName( index );
153 }
154
155 Property::Index Geometry::GetDefaultPropertyIndex( const std::string& name ) const
156 {
157   return GEOMETRY_IMPL.GetDefaultPropertyIndex( name );
158 }
159
160 bool Geometry::IsDefaultPropertyWritable( Property::Index index ) const
161 {
162   return GEOMETRY_IMPL.IsDefaultPropertyWritable( index );
163 }
164
165 bool Geometry::IsDefaultPropertyAnimatable( Property::Index index ) const
166 {
167   return GEOMETRY_IMPL.IsDefaultPropertyAnimatable( index );
168 }
169
170 bool Geometry::IsDefaultPropertyAConstraintInput( Property::Index index ) const
171 {
172   return GEOMETRY_IMPL.IsDefaultPropertyAConstraintInput( index );
173 }
174
175 Property::Type Geometry::GetDefaultPropertyType( Property::Index index ) const
176 {
177   return GEOMETRY_IMPL.GetDefaultPropertyType( index );
178 }
179
180 void Geometry::SetDefaultProperty( Property::Index index,
181                                    const Property::Value& propertyValue )
182 {
183   switch( index )
184   {
185     case Dali::Geometry::Property::GEOMETRY_TYPE :
186     {
187       SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mGeometryType, &SceneGraph::DoubleBufferedProperty<int>::Set, propertyValue.Get<int>() );
188       break;
189     }
190     case Dali::Geometry::Property::GEOMETRY_CENTER :
191     {
192       SceneGraph::AnimatablePropertyMessage<Vector3>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mCenter, &SceneGraph::AnimatableProperty<Vector3>::Bake, propertyValue.Get<Vector3>() );
193       break;
194     }
195     case Dali::Geometry::Property::REQUIRES_DEPTH_TEST :
196     {
197       SceneGraph::DoubleBufferedPropertyMessage<bool>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mRequiresDepthTest, &SceneGraph::DoubleBufferedProperty<bool>::Set, propertyValue.Get<bool>() );
198       break;
199     }
200   }
201 }
202
203 void Geometry::SetSceneGraphProperty( Property::Index index,
204                                       const PropertyMetadata& entry,
205                                       const Property::Value& value )
206 {
207   GEOMETRY_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
208 }
209
210 Property::Value Geometry::GetDefaultProperty( Property::Index index ) const
211 {
212   BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
213   Property::Value value;
214
215   switch( index )
216   {
217     case Dali::Geometry::Property::GEOMETRY_TYPE :
218     {
219       if( mSceneObject )
220       {
221         value = mSceneObject->mGeometryType[bufferIndex];
222       }
223       break;
224     }
225     case Dali::Geometry::Property::GEOMETRY_CENTER :
226     {
227       if( mSceneObject )
228       {
229         value = mSceneObject->mCenter[bufferIndex];
230       }
231       break;
232     }
233
234     case Dali::Geometry::Property::REQUIRES_DEPTH_TEST :
235     {
236       if( mSceneObject )
237       {
238         value = mSceneObject->mRequiresDepthTest[bufferIndex];
239       }
240       break;
241     }
242   }
243
244   return value;
245 }
246
247 const SceneGraph::PropertyOwner* Geometry::GetPropertyOwner() const
248 {
249   return mSceneObject;
250 }
251
252 const SceneGraph::PropertyOwner* Geometry::GetSceneObject() const
253 {
254   return mSceneObject;
255 }
256
257 const SceneGraph::PropertyBase* Geometry::GetSceneObjectAnimatableProperty( Property::Index index ) const
258 {
259   const SceneGraph::PropertyBase* property = NULL;
260
261   if( OnStage() )
262   {
263     property = GEOMETRY_IMPL.GetRegisteredSceneGraphProperty ( this,
264                                                                &Geometry::FindAnimatableProperty,
265                                                                &Geometry::FindCustomProperty,
266                                                                index );
267
268     if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
269     {
270       switch(index)
271       {
272         case Dali::Geometry::Property::GEOMETRY_CENTER :
273         {
274           property = &mSceneObject->mCenter;
275           break;
276         }
277         default:
278         {
279           DALI_ASSERT_ALWAYS( 0 && "Property is not animatable" );
280           break;
281         }
282       }
283     }
284   }
285   return property;
286 }
287
288 const PropertyInputImpl* Geometry::GetSceneObjectInputProperty( Property::Index index ) const
289 {
290   const PropertyInputImpl* property = NULL;
291
292   if( OnStage() )
293   {
294     const SceneGraph::PropertyBase* baseProperty =
295       GEOMETRY_IMPL.GetRegisteredSceneGraphProperty ( this,
296                                                       &Geometry::FindAnimatableProperty,
297                                                       &Geometry::FindCustomProperty,
298                                                       index );
299
300     property = static_cast<const PropertyInputImpl*>( baseProperty );
301
302     if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
303     {
304       switch(index)
305       {
306         case Dali::Geometry::Property::GEOMETRY_TYPE :
307         {
308           property = &mSceneObject->mGeometryType;
309           break;
310         }
311         case Dali::Geometry::Property::GEOMETRY_CENTER :
312         {
313           property = &mSceneObject->mCenter;
314           break;
315         }
316         case Dali::Geometry::Property::REQUIRES_DEPTH_TEST :
317         {
318           property = &mSceneObject->mRequiresDepthTest;
319           break;
320         }
321         default:
322         {
323           DALI_ASSERT_ALWAYS( 0 && "Property cannot be a constraint input");
324           break;
325         }
326       }
327     }
328   }
329
330   return property;
331 }
332
333 int Geometry::GetPropertyComponentIndex( Property::Index index ) const
334 {
335   // @todo MESH_REWORK - Change this if component properties are added for center/half-extent
336   return Property::INVALID_COMPONENT_INDEX;
337 }
338
339 bool Geometry::OnStage() const
340 {
341   return mOnStage;
342 }
343
344 void Geometry::Connect()
345 {
346   mOnStage = true;
347
348   PropertyBufferConnectorContainer::const_iterator end = mVertexBufferConnectors.end();
349   for( PropertyBufferConnectorContainer::iterator it = mVertexBufferConnectors.begin();
350        it < end;
351        ++it )
352   {
353     it->OnStageConnect();
354   }
355   mIndexBufferConnector.OnStageConnect();
356 }
357
358 void Geometry::Disconnect()
359 {
360   mOnStage = false;
361
362   PropertyBufferConnectorContainer::const_iterator end = mVertexBufferConnectors.end();
363   for( PropertyBufferConnectorContainer::iterator it = mVertexBufferConnectors.begin();
364        it < end;
365        ++it )
366   {
367     it->OnStageDisconnect();
368   }
369   mIndexBufferConnector.OnStageDisconnect();
370 }
371
372 Geometry::Geometry()
373 : mSceneObject( NULL ),
374   mOnStage( false )
375 {
376 }
377
378 void Geometry::Initialize()
379 {
380   EventThreadServices& eventThreadServices = GetEventThreadServices();
381   SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
382
383   mSceneObject = new SceneGraph::Geometry();
384   AddMessage( updateManager, updateManager.GetGeometryOwner(), *mSceneObject );
385
386   eventThreadServices.RegisterObject( this );
387 }
388
389 Geometry::~Geometry()
390 {
391   if( EventThreadServices::IsCoreRunning() )
392   {
393     EventThreadServices& eventThreadServices = GetEventThreadServices();
394     SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
395     RemoveMessage( updateManager, updateManager.GetGeometryOwner(), *mSceneObject );
396
397     eventThreadServices.UnregisterObject( this );
398   }
399 }
400
401
402 } // namespace Internal
403 } // namespace Dali