Fixed dynamic shapes using meshes.
authorDavid Steele <david.steele@partner.samsung.com>
Thu, 15 May 2014 19:28:33 +0000 (20:28 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 27 May 2014 14:20:54 +0000 (15:20 +0100)
[problem]      Cloth demos crash
[cause]        DynamicsShape of type mesh is using discardable meshes
[solution]     Need to ensure that the meshes used for dynamics shapes are not
               discardable. Needs a new API to create mesh actors from such a mesh.
               (Don't want to have non-discardable meshes in public API)

New API is:
Cloth cloth = Cloth::New(width, height, numXDivisions, numYDivisions);
DynamicsShape meshShape = DynamicsShape::NewMesh( cloth );
MeshActor clothActor = MeshActor::New( cloth );

Change-Id: I5c89bfd481d6162f8f17e03710c320e8fbb249bf
Signed-off-by: David Steele <david.steele@partner.samsung.com>
22 files changed:
automated-tests/src/dali-unmanaged/utc-Dali-DynamicsBody.cpp
automated-tests/src/dali-unmanaged/utc-Dali-DynamicsShape.cpp
dali/internal/event/dynamics/dynamics-body-config-impl.cpp
dali/internal/event/dynamics/dynamics-mesh-shape-impl.cpp
dali/internal/event/dynamics/dynamics-mesh-shape-impl.h
dali/internal/event/modeling/cloth-impl.cpp [new file with mode: 0644]
dali/internal/event/modeling/cloth-impl.h [new file with mode: 0644]
dali/internal/file.list
dali/internal/update/modeling/scene-graph-mesh.cpp
dali/internal/update/modeling/scene-graph-mesh.h
dali/internal/update/resources/resource-manager.cpp
dali/public-api/dali-core.h
dali/public-api/dynamics/dynamics-shape.cpp
dali/public-api/dynamics/dynamics-shape.h
dali/public-api/file.list
dali/public-api/geometry/cloth.cpp [new file with mode: 0644]
dali/public-api/geometry/cloth.h [new file with mode: 0644]
dali/public-api/geometry/mesh-data.h
dali/public-api/geometry/mesh-factory.cpp [new file with mode: 0644]
dali/public-api/geometry/mesh-factory.h [new file with mode: 0644]
dali/public-api/geometry/mesh.cpp
dali/public-api/geometry/mesh.h

index 70bc5b7..35d2f2e 100644 (file)
@@ -447,7 +447,7 @@ int UtcDaliDynamicsBodyAddAnchor(void)
 
   DynamicsBodyConfig softConfig( DynamicsBodyConfig::New() );
   softConfig.SetType(DynamicsBodyConfig::SOFT);
-  Mesh mesh(Mesh::NewPlane(10.0f, 10.0f, 10, 10));
+  Cloth mesh(Cloth::New(10.0f, 10.0f, 10, 10));
   DynamicsShape meshShape(DynamicsShape::NewMesh(mesh));
   softConfig.SetShape( meshShape );
   softConfig.SetMass(1.0f);
index 26de1e4..a6eba51 100644 (file)
@@ -193,7 +193,7 @@ int UtcDaliDynamicsShapeNewMesh(void)
 
   if( world )
   {
-    DynamicsShape shape( DynamicsShape::NewMesh( Mesh::NewPlane(10.0f, 10.0f, 10, 10)) );
+    DynamicsShape shape( DynamicsShape::NewMesh( Cloth::New(10.0f, 10.0f, 10, 10)) );
 
     DALI_TEST_CHECK( shape );
     DALI_TEST_CHECK( DynamicsShape::MESH == shape.GetType() );
index 5515c77..a83a144 100644 (file)
@@ -30,6 +30,7 @@
 #include <dali/internal/event/dynamics/dynamics-mesh-shape-impl.h>
 #include <dali/internal/event/dynamics/dynamics-sphere-shape-impl.h>
 #include <dali/internal/event/modeling/mesh-impl.h>
+#include <dali/public-api/geometry/cloth.h>
 
 namespace Dali
 {
@@ -102,8 +103,8 @@ void DynamicsBodyConfig::SetShape( const Dali::DynamicsShape::ShapeType type, co
     }
     case Dali::DynamicsShape::MESH:
     {
-      Dali::Mesh mesh( Dali::Mesh::NewPlane( dimensions.x, dimensions.y, dimensions.z, dimensions.z ) );
-      mShape = new DynamicsMeshShape( GetImplementation(mesh) );
+      Dali::Cloth cloth = Dali::Cloth::New( dimensions.x, dimensions.y, dimensions.z, dimensions.z );
+      mShape = new DynamicsMeshShape( GetImplementation(cloth) );
       break;
     }
     case Dali::DynamicsShape::SPHERE:
index bfddf27..4b110e6 100644 (file)
@@ -32,7 +32,7 @@ namespace Internal
 
 DynamicsMeshShape::DynamicsMeshShape(Mesh& mesh)
 : DynamicsShape(Dali::DynamicsShape::MESH),
-  mMesh( &mesh )
+  mMesh( mesh )
 {
   DALI_LOG_INFO(Debug::Filter::gDynamics, Debug::Verbose, "%s\n", __PRETTY_FUNCTION__);
 
@@ -41,7 +41,7 @@ DynamicsMeshShape::DynamicsMeshShape(Mesh& mesh)
   DALI_ASSERT_ALWAYS( world && "No Dynamics World !");
   ResourceManager& resourceManager( ThreadLocalStorage::Get().GetResourceManager() );
 
-  SceneGraph::DynamicsMeshShape* meshShape( new SceneGraph::DynamicsMeshShape( *world->GetSceneObject(), resourceManager, mesh.GetResourceId()) );
+  SceneGraph::DynamicsMeshShape* meshShape( new SceneGraph::DynamicsMeshShape( *world->GetSceneObject(), resourceManager, mMesh.GetResourceId()) );
   mDynamicsShape = meshShape;
 
   // Queue a message to ensure the underlying dynamics object is created in the update thread
index 0fc6231..f954944 100644 (file)
@@ -65,8 +65,16 @@ public:
    */
   virtual Vector3 GetAABB() const;
 
+  /**
+   * Get the mesh
+   */
+  Mesh& GetMesh()
+  {
+    return mMesh;
+  }
+
 private:
-  MeshIPtr mMesh;
+  Mesh& mMesh;
 }; // class DynamicsMeshShape
 
 } // namespace Internal
diff --git a/dali/internal/event/modeling/cloth-impl.cpp b/dali/internal/event/modeling/cloth-impl.cpp
new file mode 100644 (file)
index 0000000..195a07c
--- /dev/null
@@ -0,0 +1,49 @@
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// CLASS HEADER
+#include <dali/internal/event/modeling/cloth-impl.h>
+
+// EXTERNAL INCLUDES
+#include <stdio.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/modeling/mesh-impl.h>
+
+using namespace std;
+
+namespace Dali
+{
+namespace Internal
+{
+
+ClothIPtr Cloth::New( const Dali::MeshData& meshData )
+{
+  ClothIPtr cloth( new Cloth( meshData ) );
+  return cloth;
+}
+
+Cloth::Cloth( const Dali::MeshData& publicMeshData )
+: Mesh( publicMeshData, false /* not discardable */, false /* not scalable */ )
+{
+}
+
+Cloth::~Cloth()
+{
+}
+
+} // namespace Internal
+} // namespace Dali
diff --git a/dali/internal/event/modeling/cloth-impl.h b/dali/internal/event/modeling/cloth-impl.h
new file mode 100644 (file)
index 0000000..5654b25
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef __DALI_INTERNAL_CLOTH_H__
+#define __DALI_INTERNAL_CLOTH_H__
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// INTERNAL INCLUDES
+#include <dali/public-api/geometry/cloth.h>
+#include <dali/internal/event/modeling/mesh-impl.h>
+
+namespace Dali
+{
+class MeshData;
+
+namespace Internal
+{
+class Cloth;
+
+typedef IntrusivePtr<Cloth> ClothIPtr; ///< smart pointer to a Cloth
+
+/**
+ * A single cloth in a 3D model
+ */
+class Cloth : public Mesh
+{
+public: // construction, destruction and initialisation
+
+  /**
+   * Create a new cloth.
+   * @param[in] clothData the mesh data
+   * @return A smart-pointer to the newly allocated Cloth.
+   */
+  static ClothIPtr New( const Dali::MeshData& clothData );
+
+  /**
+   * Construct a new Cloth. This is not discardable or scalable.
+   * @param[in] clothData the mesh data
+   */
+  Cloth( const Dali::MeshData& clothData );
+
+protected:
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~Cloth();
+
+private:
+  // Undefined
+  Cloth(const Cloth&);
+
+  // Undefined
+  Cloth& operator=(const Cloth& rhs);
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::Cloth& GetImplementation(Dali::Cloth& cloth)
+{
+  DALI_ASSERT_ALWAYS( cloth && "Cloth handle is empty" );
+
+  BaseObject& handle = cloth.GetBaseObject();
+
+  return static_cast<Internal::Cloth&>(handle);
+}
+
+inline const Internal::Cloth& GetImplementation(const Dali::Cloth& cloth)
+{
+  DALI_ASSERT_ALWAYS( cloth && "Cloth handle is empty" );
+
+  const BaseObject& handle = cloth.GetBaseObject();
+
+  return static_cast<const Internal::Cloth&>(handle);
+}
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_CLOTH_H__
index faaba12..ecb527c 100644 (file)
@@ -75,6 +75,7 @@ internal_src_files = \
   $(internal_src_dir)/event/images/nine-patch-image-impl.cpp \
   $(internal_src_dir)/event/images/emoji-factory.cpp \
   $(internal_src_dir)/event/modeling/animatable-mesh-impl.cpp \
+  $(internal_src_dir)/event/modeling/cloth-impl.cpp \
   $(internal_src_dir)/event/modeling/entity-impl.cpp \
   $(internal_src_dir)/event/modeling/light-impl.cpp \
   $(internal_src_dir)/event/modeling/material-impl.cpp \
index 90bfe7a..d934143 100644 (file)
@@ -20,6 +20,7 @@
 // INTERNAL INCLUDES
 #include <dali/internal/render/common/post-process-resource-dispatcher.h>
 #include <dali/internal/render/gl-resources/context.h>
+#include <dali/internal/render/queue/render-queue.h>
 
 using namespace std;
 
@@ -34,16 +35,19 @@ namespace SceneGraph
 
 Mesh::Mesh( ResourceId id,
             PostProcessResourceDispatcher& postProcessResourceDispatcher,
+            RenderQueue& renderQueue,
             MeshData* meshData )
-: mResourceId ( id ),
+:
+  mPostProcessResourceDispatcher(postProcessResourceDispatcher),
+  mRenderQueue(renderQueue),
   mUpdateMeshData(meshData),
   mRenderMeshData(meshData),
-  mRefreshVertexBuffer(true),
   mVertexBuffer(NULL),
   mIndicesBuffer(NULL),
   mNumberOfVertices(0u),
   mNumberOfFaces(0u),
-  mPostProcessResourceDispatcher(postProcessResourceDispatcher)
+  mResourceId ( id ),
+  mRefreshVertexBuffer(true)
 {
 }
 
@@ -69,6 +73,7 @@ const MeshData& Mesh::GetMeshData( Mesh::ThreadBuffer threadBuffer ) const
   {
     case Mesh::UPDATE_THREAD:
     {
+
       meshDataPtr = mUpdateMeshData;
     }
     break;
@@ -84,21 +89,30 @@ const MeshData& Mesh::GetMeshData( Mesh::ThreadBuffer threadBuffer ) const
   return *meshDataPtr;
 }
 
+void Mesh::RefreshVertexBuffer()
+{
+    mRefreshVertexBuffer = true;
+}
+
 void Mesh::MeshDataUpdated( BufferIndex bufferIndex, Mesh::ThreadBuffer threadBuffer, MeshData* meshData )
 {
   if ( threadBuffer == Mesh::RENDER_THREAD )
   {
     // Called from a message, the old MeshData will be release and the new one is saved.
     mRenderMeshData = meshData;
+    RefreshVertexBuffer();
   }
   else
   {
     // Dynamics and animatable meshes don't create new mesh data
     DALI_ASSERT_DEBUG( threadBuffer == Mesh::UPDATE_THREAD );
     DALI_ASSERT_DEBUG( meshData == NULL );
-  }
 
-  mRefreshVertexBuffer = true;
+    // Send a message to self in render thread
+    typedef Message< Mesh > LocalType;
+    unsigned int* slot = mRenderQueue.ReserveMessageSlot( bufferIndex, sizeof( LocalType ) );
+    new (slot) LocalType( this, &Mesh::RefreshVertexBuffer);
+  }
 }
 
 void Mesh::UploadVertexData( Context& context, BufferIndex renderBufferIndex )
index 0f0e027..3f6a1a4 100644 (file)
@@ -36,7 +36,7 @@ namespace Internal
 
 namespace SceneGraph
 {
-
+class RenderQueue;
 class PostProcessResourceDispatcher;
 class Mesh;
 
@@ -62,9 +62,10 @@ public:
    */
   static Mesh* New( ResourceId id,
                     PostProcessResourceDispatcher& postProcessResourceDispatcher,
+                    RenderQueue& renderQueue,
                     MeshData* meshData )
   {
-    return new Mesh( id, postProcessResourceDispatcher, meshData );
+    return new Mesh( id, postProcessResourceDispatcher, renderQueue, meshData );
   }
 
   /**
@@ -146,12 +147,17 @@ public: // from GlResourceOwner
   virtual void GlCleanup();
 
 private:
+  /**
+   * Method to set if the vertex buffer should be refreshed in the render thread
+   */
+  void RefreshVertexBuffer();
 
   /**
    * Private constructor; see also Mesh::New()
    */
   Mesh( ResourceId id,
         PostProcessResourceDispatcher& postProcessResourceDispatcher,
+        RenderQueue& renderQueue,
         MeshData* meshData );
 
   // Undefined
@@ -161,24 +167,20 @@ private:
   Mesh& operator=(const Mesh& rhs);
 
 protected:
-
-  ResourceId mResourceId;
-
+  PostProcessResourceDispatcher& mPostProcessResourceDispatcher;
+  SceneGraph::RenderQueue& mRenderQueue;
   /**
    * The mUpdateMeshData will point to a mesh data that was just received
    * or to the MeshData pointed by mRenderMeshData if it's more that one frame old
-   **/
+   */
   MeshData* mUpdateMeshData;              ///< Pointer to MeshData object
   OwnerPointer<MeshData> mRenderMeshData; ///< Owner of the MeshData Object
-
-  bool mRefreshVertexBuffer;              ///< True when GpuBuffers need updating
   OwnerPointer<GpuBuffer> mVertexBuffer;  ///< Vertex buffer
   OwnerPointer<GpuBuffer> mIndicesBuffer; ///< Index buffer
-
   size_t     mNumberOfVertices;    ///< Number of vertices
   size_t     mNumberOfFaces;       ///< Number of faces
-
-  PostProcessResourceDispatcher& mPostProcessResourceDispatcher;
+  ResourceId mResourceId;
+  bool mRefreshVertexBuffer;              ///< True when GpuBuffers need updating
 };
 
 } // namespace SceneGraph
index d935e18..92fb658 100644 (file)
@@ -371,7 +371,7 @@ void ResourceManager::HandleAllocateMeshRequest( ResourceId id, MeshData* meshDa
 {
   DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAllocateMeshRequest(id:%u)\n", id);
 
-  SceneGraph::Mesh* renderableMesh(SceneGraph::Mesh::New(id, mImpl->mPostProcessResourceDispatcher, meshData));
+  SceneGraph::Mesh* renderableMesh(SceneGraph::Mesh::New(id, mImpl->mPostProcessResourceDispatcher, mImpl->mRenderQueue, meshData));
 
   DALI_ASSERT_ALWAYS(renderableMesh && "renderableMesh not created");
 
index d6f8ae2..2243e0c 100644 (file)
@@ -41,7 +41,9 @@
 #include <dali/public-api/events/hit-test-algorithm.h>
 #include <dali/public-api/events/mouse-wheel-event.h>
 
+#include <dali/public-api/geometry/cloth.h>
 #include <dali/public-api/geometry/mesh.h>
+#include <dali/public-api/geometry/mesh-factory.h>
 #include <dali/public-api/geometry/spline.h>
 
 #include <dali/public-api/images/distance-field.h>
index 21e4dc7..2bf6c29 100644 (file)
@@ -78,10 +78,10 @@ DynamicsShape DynamicsShape::NewCylinder(const float radius, const float length)
 #endif
 }
 
-DynamicsShape DynamicsShape::NewMesh(Mesh mesh)
+DynamicsShape DynamicsShape::NewMesh(Cloth cloth)
 {
 #ifdef DYNAMICS_SUPPORT
-  Internal::DynamicsMeshShapePtr internal( new Internal::DynamicsMeshShape( GetImplementation(mesh) ) );
+  Internal::DynamicsMeshShapePtr internal( new Internal::DynamicsMeshShape( GetImplementation(cloth) ) );
 
   return DynamicsShape(internal.Get());
 #else
index 96789cf..18bf0cc 100644 (file)
@@ -22,6 +22,7 @@
 
 // BASE CLASS INCLUDES
 #include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/geometry/cloth.h>
 
 namespace Dali DALI_IMPORT_API
 {
@@ -31,7 +32,6 @@ namespace Internal DALI_INTERNAL
 class DynamicsShape;
 } // namespace Internal
 
-class Mesh;
 class DynamicsWorld;
 
 /**
@@ -96,7 +96,7 @@ public:
    * @param[in] mesh  A mesh.
    * @return A handle to the new shape
    */
-  static DynamicsShape NewMesh(Mesh mesh);
+  static DynamicsShape NewMesh(Cloth mesh);
 
   /**
    * @brief Creates a sphere.
index 93ff1c8..66a3569 100644 (file)
@@ -52,7 +52,9 @@ public_api_src_files = \
   $(public_api_src_dir)/events/touch-event.cpp \
   $(public_api_src_dir)/geometry/animatable-mesh.cpp \
   $(public_api_src_dir)/geometry/animatable-vertex.cpp \
+  $(public_api_src_dir)/geometry/cloth.cpp \
   $(public_api_src_dir)/geometry/mesh-data.cpp \
+  $(public_api_src_dir)/geometry/mesh-factory.cpp \
   $(public_api_src_dir)/geometry/mesh.cpp \
   $(public_api_src_dir)/geometry/spline.cpp \
   $(public_api_src_dir)/images/distance-field.cpp \
@@ -147,8 +149,10 @@ public_api_core_events_header_files = \
   $(public_api_src_dir)/events/mouse-wheel-event.h
 
 public_api_core_geometry_header_files = \
+  $(public_api_src_dir)/geometry/cloth.h \
   $(public_api_src_dir)/geometry/mesh.h \
   $(public_api_src_dir)/geometry/mesh-data.h \
+  $(public_api_src_dir)/geometry/mesh-factory.h \
   $(public_api_src_dir)/geometry/spline.h
 
 public_api_core_images_header_files = \
diff --git a/dali/public-api/geometry/cloth.cpp b/dali/public-api/geometry/cloth.cpp
new file mode 100644 (file)
index 0000000..8ba21dc
--- /dev/null
@@ -0,0 +1,58 @@
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// CLASS HEADER
+#include <dali/public-api/geometry/cloth.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/geometry/mesh-factory.h>
+#include <dali/internal/event/modeling/cloth-impl.h>
+
+namespace Dali
+{
+
+namespace
+{
+
+} // namespace
+
+Cloth::Cloth()
+{
+}
+
+Cloth::~Cloth()
+{
+}
+
+Cloth Cloth::New( const float width, const float height, const int xSteps, const int ySteps, const Rect<float>& textureCoordinates )
+{
+  MeshData meshData( MeshFactory::NewPlane(width, height, xSteps, ySteps, textureCoordinates) );
+
+  Internal::ClothIPtr clothPtr = Internal::Cloth::New( meshData );
+  return Cloth( clothPtr.Get() );
+}
+
+Cloth Cloth::DownCast( BaseHandle handle )
+{
+  return Cloth( dynamic_cast<Dali::Internal::Cloth*>(handle.GetObjectPtr()) );
+}
+
+Cloth::Cloth(Internal::Cloth* internal)
+: Mesh(internal)
+{
+}
+
+} // namespace Dali
diff --git a/dali/public-api/geometry/cloth.h b/dali/public-api/geometry/cloth.h
new file mode 100644 (file)
index 0000000..5e5d9e6
--- /dev/null
@@ -0,0 +1,100 @@
+#ifndef __DALI_CLOTH_H__
+#define __DALI_CLOTH_H__
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+
+// INTERNAL INCLUDES
+#include <dali/public-api/math/rect.h>
+#include <dali/public-api/math/vector4.h>
+#include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/geometry/mesh.h>
+
+namespace Dali DALI_IMPORT_API
+{
+
+namespace Internal DALI_INTERNAL
+{
+class Cloth;
+}
+
+/**
+ * @brief A Cloth is a specialized mesh that can be used and modified
+ * by the Dynamics engine.
+ */
+class Cloth : public Mesh
+{
+public:
+
+  /**
+   * @brief Create an initialized plane aligned on the XY axis.
+   *
+   * @param[in] width   The width of the plane
+   * @param[in] height  The height of the plane
+   * @param[in] xSteps  The number of vertices along the X axis
+   * @param[in] ySteps  The number of vertices along the Y axis
+   * @param[in] textureCoordinates  UV coordinates.
+   * @return A handle to a newly allocated Dali resource.
+   */
+  static Cloth New(const float width,
+                   const float height,
+                   const int xSteps,
+                   const int ySteps,
+                   const Rect<float>& textureCoordinates = Rect<float>(0.0f, 0.0f, 1.0f, 1.0f));
+
+
+  /**
+   * @brief Create an uninitialized Cloth; this can be initialized with Cloth::New().
+   *
+   * Calling member functions with an uninitialized Dali::Object is not allowed.
+   */
+  Cloth();
+
+  /**
+   * @brief Virtual destructor.
+   */
+  virtual ~Cloth();
+
+  /**
+   * @copydoc Dali::BaseHandle::operator=
+   */
+  using BaseHandle::operator=;
+
+  /**
+   * @brief Downcast an Object handle to a Cloth handle.
+   *
+   * If handle points to a Cloth object the downcast produces valid
+   * handle. If not the returned handle is left uninitialized.
+   *
+   * @param[in] handle to an object
+   * @return handle to a Cloth object or an uninitialized handle
+   */
+  static Cloth DownCast( BaseHandle handle );
+
+public: // Not intended for application developers
+
+  /**
+   * @brief This constructor is used by Dali New() methods.
+   *
+   * @param [in] cloth A pointer to a newly allocated Dali resource
+   */
+  explicit DALI_INTERNAL Cloth(Internal::Cloth* cloth);
+};
+
+} // namespace Dali
+
+#endif // __DALI_CLOTH_H__
index b56bf8d..1c04d4b 100644 (file)
@@ -104,7 +104,7 @@ public: // construction, destruction and initialisation
    *
    * @param[in] meshData object to copy
    */
-  explicit MeshData( const MeshData& meshData );
+  MeshData( const MeshData& meshData );
 
   /**
    * @brief Assignment operator.
diff --git a/dali/public-api/geometry/mesh-factory.cpp b/dali/public-api/geometry/mesh-factory.cpp
new file mode 100644 (file)
index 0000000..439c96b
--- /dev/null
@@ -0,0 +1,108 @@
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "mesh-factory.h"
+
+#include <dali/public-api/geometry/mesh-data.h>
+#include <dali/public-api/modeling/material.h>
+
+namespace Dali
+{
+namespace MeshFactory
+{
+
+Dali::MeshData NewPlane(const float width, const float height, const int xSteps, const int ySteps, const Rect<float>& textureCoordinates)
+{
+  DALI_ASSERT_DEBUG( xSteps > 1 && ySteps > 1 );
+
+  const int vertexCount = xSteps * ySteps;
+
+  // vertices
+  MeshData::VertexContainer vertices(vertexCount);
+  const float xSpacing = width / ( xSteps - 1 );
+  const float ySpacing = height / (ySteps - 1 );
+  const float xOffset = -xSpacing * (0.5f * xSteps) + (0.5f * xSpacing);      // origin at (width / 2, height / 2)
+  const float yOffset = -ySpacing * (0.5f * ySteps) + (0.5f * ySpacing);
+  const float xSpacingUV = textureCoordinates.width / (xSteps - 1);
+  const float ySpacingUV = textureCoordinates.height / (ySteps - 1);
+  int vertexIndex = 0;
+  for( int y = 0; y < ySteps; ++y )
+  {
+    for( int x = 0; x < xSteps; ++x )
+    {
+      MeshData::Vertex& vertex = vertices[vertexIndex];
+      vertex.x = xOffset + (xSpacing * x);
+      vertex.y = yOffset + (ySpacing * y);
+      vertex.z = 0.0f;
+
+      vertex.nX = 0.0f;
+      vertex.nY = 0.0f;
+      vertex.nZ = 1.0f;
+
+      vertex.u = textureCoordinates.x + (xSpacingUV * x);
+      vertex.v = textureCoordinates.y + (ySpacingUV * y);
+      ++vertexIndex;
+    }
+  }
+
+  // faces
+  const int faceCount = 2 * ((ySteps - 1) * (xSteps - 1));
+  MeshData::FaceIndices faces( faceCount * 3 );
+  unsigned short* pIndex = &(faces)[0];
+  unsigned short index0 = 0;
+  unsigned short index1 = 0;
+  unsigned short index2 = 0;
+
+  for( int y = 0; y < ySteps - 1; ++y )
+  {
+    for( int x = 0; x < xSteps - 1; ++x )
+    {
+      index0 = (y * xSteps) + x;
+      index1 = ((y + 1) * xSteps) + x;
+      index2 = ((y + 1) * xSteps) + (x + 1);
+      *pIndex++ = index0;
+      *pIndex++ = index1;
+      *pIndex++ = index2;
+
+      index0 = ((y + 1) * xSteps) + (x + 1);
+      index1 = (y * xSteps) + (x + 1);
+      index2 = (y * xSteps) + x;
+      *pIndex++ = index0;
+      *pIndex++ = index1;
+      *pIndex++ = index2;
+    }
+  }
+
+  BoneContainer bones;
+
+  Dali::MeshData meshData;
+
+  meshData.SetHasNormals(true);
+  meshData.SetHasTextureCoords(true);
+  meshData.SetData( vertices, faces, bones, Dali::Material::New("PlaneMat"));
+
+  Vector4 vMin;
+  Vector4 vMax;
+  meshData.AddToBoundingVolume(vMin, vMax, Matrix::IDENTITY);
+
+  meshData.SetBoundingBoxMin(vMin);
+  meshData.SetBoundingBoxMax(vMax);
+
+  return meshData;
+}
+
+} // MeshFactory
+} // Dali
diff --git a/dali/public-api/geometry/mesh-factory.h b/dali/public-api/geometry/mesh-factory.h
new file mode 100644 (file)
index 0000000..fdc0292
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef __DALI_MESH_FACTORY_H__
+#define __DALI_MESH_FACTORY_H__
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <dali/public-api/math/rect.h>
+
+namespace Dali
+{
+class MeshData;
+
+namespace MeshFactory
+{
+
+/**
+ * @brief Create an initialized plane aligned on the XY axis.
+ *
+ * @param[in] width   The width of the plane
+ * @param[in] height  The height of the plane
+ * @param[in] xSteps  The number of vertices along the X axis
+ * @param[in] ySteps  The number of vertices along the Y axis
+ * @param[in] textureCoordinates  UV coordinates.
+ * @return A mesh data structure containing the plane mesh
+ */
+Dali::MeshData NewPlane( const float width,
+                         const float height,
+                         const int xSteps,
+                         const int ySteps,
+                         const Rect<float>& textureCoordinates = Rect<float>(0.0f, 0.0f, 1.0f, 1.0f) );
+
+} // MeshFactory
+} // Dali
+
+#endif // __DALI_MESH_FACTORY_H__
index d014ae2..1319809 100644 (file)
@@ -20,6 +20,7 @@
 // INTERNAL INCLUDES
 #include <dali/internal/event/modeling/mesh-impl.h>
 #include <dali/internal/event/modeling/material-impl.h>
+#include <dali/public-api/geometry/mesh-factory.h>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/math/vector3.h>
 
@@ -51,80 +52,7 @@ Mesh Mesh::New( const MeshData& meshData )
 
 Mesh Mesh::NewPlane(const float width, const float height, const int xSteps, const int ySteps, const Rect<float>& textureCoordinates)
 {
-  DALI_ASSERT_DEBUG( xSteps > 1 && ySteps > 1 );
-
-  const int vertexCount = xSteps * ySteps;
-
-  // vertices
-  MeshData::VertexContainer vertices(vertexCount);
-  const float xSpacing = width / ( xSteps - 1 );
-  const float ySpacing = height / (ySteps - 1 );
-  const float xOffset = -xSpacing * (0.5f * xSteps) + (0.5f * xSpacing);      // origin at (width / 2, height / 2)
-  const float yOffset = -ySpacing * (0.5f * ySteps) + (0.5f * ySpacing);
-  const float xSpacingUV = textureCoordinates.width / (xSteps - 1);
-  const float ySpacingUV = textureCoordinates.height / (ySteps - 1);
-  int vertexIndex = 0;
-  for( int y = 0; y < ySteps; ++y )
-  {
-    for( int x = 0; x < xSteps; ++x )
-    {
-      MeshData::Vertex& vertex = vertices[vertexIndex];
-      vertex.x = xOffset + (xSpacing * x);
-      vertex.y = yOffset + (ySpacing * y);
-      vertex.z = 0.0f;
-
-      vertex.nX = 0.0f;
-      vertex.nY = 0.0f;
-      vertex.nZ = 1.0f;
-
-      vertex.u = textureCoordinates.x + (xSpacingUV * x);
-      vertex.v = textureCoordinates.y + (ySpacingUV * y);
-      ++vertexIndex;
-    }
-  }
-
-  // faces
-  const int faceCount = 2 * ((ySteps - 1) * (xSteps - 1));
-  MeshData::FaceIndices faces( faceCount * 3 );
-  unsigned short* pIndex = &(faces)[0];
-  unsigned short index0 = 0;
-  unsigned short index1 = 0;
-  unsigned short index2 = 0;
-
-  for( int y = 0; y < ySteps - 1; ++y )
-  {
-    for( int x = 0; x < xSteps - 1; ++x )
-    {
-      index0 = (y * xSteps) + x;
-      index1 = ((y + 1) * xSteps) + x;
-      index2 = ((y + 1) * xSteps) + (x + 1);
-      *pIndex++ = index0;
-      *pIndex++ = index1;
-      *pIndex++ = index2;
-
-      index0 = ((y + 1) * xSteps) + (x + 1);
-      index1 = (y * xSteps) + (x + 1);
-      index2 = (y * xSteps) + x;
-      *pIndex++ = index0;
-      *pIndex++ = index1;
-      *pIndex++ = index2;
-    }
-  }
-
-  BoneContainer bones;
-
-  MeshData meshData;
-  meshData.SetHasNormals(true);
-  meshData.SetHasTextureCoords(true);
-  meshData.SetData( vertices, faces, bones, Material::New("PlaneMat"));
-
-  Vector4 vMin;
-  Vector4 vMax;
-  meshData.AddToBoundingVolume(vMin, vMax, Matrix::IDENTITY);
-
-  meshData.SetBoundingBoxMin(vMin);
-  meshData.SetBoundingBoxMax(vMax);
-
+  MeshData meshData( MeshFactory::NewPlane(width, height, xSteps, ySteps, textureCoordinates) );
   return New(meshData);
 }
 
index 76d4a4b..0a291ea 100644 (file)
 
 
 // INTERNAL INCLUDES
-#include <dali/public-api/actors/actor.h>
 #include <dali/public-api/geometry/mesh-data.h>
 #include <dali/public-api/math/rect.h>
-#include <dali/public-api/math/vector4.h>
-#include <dali/public-api/modeling/material.h>
-#include <dali/public-api/modeling/bone.h>
 #include <dali/public-api/object/base-handle.h>
 
 namespace Dali DALI_IMPORT_API