From bf1068c9ced863a29185fe67315e766eea54c079 Mon Sep 17 00:00:00 2001 From: David Steele Date: Thu, 15 May 2014 20:28:33 +0100 Subject: [PATCH] Fixed dynamic shapes using meshes. [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 --- .../src/dali-unmanaged/utc-Dali-DynamicsBody.cpp | 2 +- .../src/dali-unmanaged/utc-Dali-DynamicsShape.cpp | 2 +- .../event/dynamics/dynamics-body-config-impl.cpp | 5 +- .../event/dynamics/dynamics-mesh-shape-impl.cpp | 4 +- .../event/dynamics/dynamics-mesh-shape-impl.h | 10 +- dali/internal/event/modeling/cloth-impl.cpp | 49 ++++++++++ dali/internal/event/modeling/cloth-impl.h | 92 ++++++++++++++++++ dali/internal/file.list | 1 + dali/internal/update/modeling/scene-graph-mesh.cpp | 24 ++++- dali/internal/update/modeling/scene-graph-mesh.h | 24 ++--- .../internal/update/resources/resource-manager.cpp | 2 +- dali/public-api/dali-core.h | 2 + dali/public-api/dynamics/dynamics-shape.cpp | 4 +- dali/public-api/dynamics/dynamics-shape.h | 4 +- dali/public-api/file.list | 4 + dali/public-api/geometry/cloth.cpp | 58 +++++++++++ dali/public-api/geometry/cloth.h | 100 +++++++++++++++++++ dali/public-api/geometry/mesh-data.h | 2 +- dali/public-api/geometry/mesh-factory.cpp | 108 +++++++++++++++++++++ dali/public-api/geometry/mesh-factory.h | 47 +++++++++ dali/public-api/geometry/mesh.cpp | 76 +-------------- dali/public-api/geometry/mesh.h | 4 - 22 files changed, 517 insertions(+), 107 deletions(-) create mode 100644 dali/internal/event/modeling/cloth-impl.cpp create mode 100644 dali/internal/event/modeling/cloth-impl.h create mode 100644 dali/public-api/geometry/cloth.cpp create mode 100644 dali/public-api/geometry/cloth.h create mode 100644 dali/public-api/geometry/mesh-factory.cpp create mode 100644 dali/public-api/geometry/mesh-factory.h diff --git a/automated-tests/src/dali-unmanaged/utc-Dali-DynamicsBody.cpp b/automated-tests/src/dali-unmanaged/utc-Dali-DynamicsBody.cpp index 70bc5b7..35d2f2e 100644 --- a/automated-tests/src/dali-unmanaged/utc-Dali-DynamicsBody.cpp +++ b/automated-tests/src/dali-unmanaged/utc-Dali-DynamicsBody.cpp @@ -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); diff --git a/automated-tests/src/dali-unmanaged/utc-Dali-DynamicsShape.cpp b/automated-tests/src/dali-unmanaged/utc-Dali-DynamicsShape.cpp index 26de1e4..a6eba51 100644 --- a/automated-tests/src/dali-unmanaged/utc-Dali-DynamicsShape.cpp +++ b/automated-tests/src/dali-unmanaged/utc-Dali-DynamicsShape.cpp @@ -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() ); diff --git a/dali/internal/event/dynamics/dynamics-body-config-impl.cpp b/dali/internal/event/dynamics/dynamics-body-config-impl.cpp index 5515c77..a83a144 100644 --- a/dali/internal/event/dynamics/dynamics-body-config-impl.cpp +++ b/dali/internal/event/dynamics/dynamics-body-config-impl.cpp @@ -30,6 +30,7 @@ #include #include #include +#include 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: diff --git a/dali/internal/event/dynamics/dynamics-mesh-shape-impl.cpp b/dali/internal/event/dynamics/dynamics-mesh-shape-impl.cpp index bfddf27..4b110e6 100644 --- a/dali/internal/event/dynamics/dynamics-mesh-shape-impl.cpp +++ b/dali/internal/event/dynamics/dynamics-mesh-shape-impl.cpp @@ -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 diff --git a/dali/internal/event/dynamics/dynamics-mesh-shape-impl.h b/dali/internal/event/dynamics/dynamics-mesh-shape-impl.h index 0fc6231..f954944 100644 --- a/dali/internal/event/dynamics/dynamics-mesh-shape-impl.h +++ b/dali/internal/event/dynamics/dynamics-mesh-shape-impl.h @@ -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 index 0000000..195a07c --- /dev/null +++ b/dali/internal/event/modeling/cloth-impl.cpp @@ -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 + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include + +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 index 0000000..5654b25 --- /dev/null +++ b/dali/internal/event/modeling/cloth-impl.h @@ -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 +#include + +namespace Dali +{ +class MeshData; + +namespace Internal +{ +class Cloth; + +typedef IntrusivePtr 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(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(handle); +} + +} // namespace Dali + +#endif // __DALI_INTERNAL_CLOTH_H__ diff --git a/dali/internal/file.list b/dali/internal/file.list index faaba12..ecb527c 100644 --- a/dali/internal/file.list +++ b/dali/internal/file.list @@ -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 \ diff --git a/dali/internal/update/modeling/scene-graph-mesh.cpp b/dali/internal/update/modeling/scene-graph-mesh.cpp index 90bfe7a..d934143 100644 --- a/dali/internal/update/modeling/scene-graph-mesh.cpp +++ b/dali/internal/update/modeling/scene-graph-mesh.cpp @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include #include +#include 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 ) diff --git a/dali/internal/update/modeling/scene-graph-mesh.h b/dali/internal/update/modeling/scene-graph-mesh.h index 0f0e027..3f6a1a4 100644 --- a/dali/internal/update/modeling/scene-graph-mesh.h +++ b/dali/internal/update/modeling/scene-graph-mesh.h @@ -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 mRenderMeshData; ///< Owner of the MeshData Object - - bool mRefreshVertexBuffer; ///< True when GpuBuffers need updating OwnerPointer mVertexBuffer; ///< Vertex buffer OwnerPointer 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 diff --git a/dali/internal/update/resources/resource-manager.cpp b/dali/internal/update/resources/resource-manager.cpp index d935e18..92fb658 100644 --- a/dali/internal/update/resources/resource-manager.cpp +++ b/dali/internal/update/resources/resource-manager.cpp @@ -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"); diff --git a/dali/public-api/dali-core.h b/dali/public-api/dali-core.h index d6f8ae2..2243e0c 100644 --- a/dali/public-api/dali-core.h +++ b/dali/public-api/dali-core.h @@ -41,7 +41,9 @@ #include #include +#include #include +#include #include #include diff --git a/dali/public-api/dynamics/dynamics-shape.cpp b/dali/public-api/dynamics/dynamics-shape.cpp index 21e4dc7..2bf6c29 100644 --- a/dali/public-api/dynamics/dynamics-shape.cpp +++ b/dali/public-api/dynamics/dynamics-shape.cpp @@ -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 diff --git a/dali/public-api/dynamics/dynamics-shape.h b/dali/public-api/dynamics/dynamics-shape.h index 96789cf..18bf0cc 100644 --- a/dali/public-api/dynamics/dynamics-shape.h +++ b/dali/public-api/dynamics/dynamics-shape.h @@ -22,6 +22,7 @@ // BASE CLASS INCLUDES #include +#include 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. diff --git a/dali/public-api/file.list b/dali/public-api/file.list index 93ff1c8..66a3569 100644 --- a/dali/public-api/file.list +++ b/dali/public-api/file.list @@ -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 index 0000000..8ba21dc --- /dev/null +++ b/dali/public-api/geometry/cloth.cpp @@ -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 + +// INTERNAL INCLUDES +#include +#include + +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& 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(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 index 0000000..5e5d9e6 --- /dev/null +++ b/dali/public-api/geometry/cloth.h @@ -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 +#include +#include +#include + +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& textureCoordinates = Rect(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__ diff --git a/dali/public-api/geometry/mesh-data.h b/dali/public-api/geometry/mesh-data.h index b56bf8d..1c04d4b 100644 --- a/dali/public-api/geometry/mesh-data.h +++ b/dali/public-api/geometry/mesh-data.h @@ -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 index 0000000..439c96b --- /dev/null +++ b/dali/public-api/geometry/mesh-factory.cpp @@ -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 +#include + +namespace Dali +{ +namespace MeshFactory +{ + +Dali::MeshData NewPlane(const float width, const float height, const int xSteps, const int ySteps, const Rect& 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 index 0000000..fdc0292 --- /dev/null +++ b/dali/public-api/geometry/mesh-factory.h @@ -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 + +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& textureCoordinates = Rect(0.0f, 0.0f, 1.0f, 1.0f) ); + +} // MeshFactory +} // Dali + +#endif // __DALI_MESH_FACTORY_H__ diff --git a/dali/public-api/geometry/mesh.cpp b/dali/public-api/geometry/mesh.cpp index d014ae2..1319809 100644 --- a/dali/public-api/geometry/mesh.cpp +++ b/dali/public-api/geometry/mesh.cpp @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include #include +#include #include #include @@ -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& 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); } diff --git a/dali/public-api/geometry/mesh.h b/dali/public-api/geometry/mesh.h index 76d4a4b..0a291ea 100644 --- a/dali/public-api/geometry/mesh.h +++ b/dali/public-api/geometry/mesh.h @@ -19,12 +19,8 @@ // INTERNAL INCLUDES -#include #include #include -#include -#include -#include #include namespace Dali DALI_IMPORT_API -- 2.7.4