Toshihiro Shimizu 890ddd
#ifndef PLASTIDEFORMERSTORAGE_H
Toshihiro Shimizu 890ddd
#define PLASTIDEFORMERSTORAGE_H
Toshihiro Shimizu 890ddd
Shinya Kitaoka 262a92
#include <memory></memory>
Shinya Kitaoka 262a92
Toshihiro Shimizu 890ddd
// TnzExt includes
Toshihiro Shimizu 890ddd
#include "ext/plasticdeformer.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#undef DVAPI
Toshihiro Shimizu 890ddd
#undef DVVAR
Toshihiro Shimizu 890ddd
#ifdef TNZEXT_EXPORTS
Toshihiro Shimizu 890ddd
#define DVAPI DV_EXPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_EXPORT_VAR
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define DVAPI DV_IMPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_IMPORT_VAR
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=======================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//    Forward Declarations
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct PlasticVisualSettings;
Toshihiro Shimizu 890ddd
struct DrawableMeshImage;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class PlasticSkeletonDeformation;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=======================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//***********************************************************************************************
Toshihiro Shimizu 890ddd
//    PlasticDeformerData  declaration
Toshihiro Shimizu 890ddd
//***********************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! PlasticDeformerData contains all the data needed to perform the deformation of a single mesh.
Toshihiro Shimizu 890ddd
struct DVAPI PlasticDeformerData {
Toshihiro Shimizu 890ddd
	PlasticDeformer m_deformer; //!< The mesh deformer itself
Toshihiro Shimizu 890ddd
Shinya Kitaoka 42bfb6
	std::unique_ptr<double[]> m_so;	 //!< (owned) Faces' stacking order</double[]>
Shinya Kitaoka 42bfb6
	std::unique_ptr<double[]> m_output; //!< (owned) Output vertex coordinates</double[]>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<int> m_faceHints; //!< Handles' face hints</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	PlasticDeformerData();
Toshihiro Shimizu 890ddd
	~PlasticDeformerData();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	// Not copyable
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PlasticDeformerData(const PlasticDeformerData &);
Toshihiro Shimizu 890ddd
	PlasticDeformerData &operator=(const PlasticDeformerData &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//***********************************************************************************************
Toshihiro Shimizu 890ddd
//    PlasticDeformerDataGroup  definition
Toshihiro Shimizu 890ddd
//***********************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct DVAPI PlasticDeformerDataGroup {
Shinya Kitaoka 42bfb6
	std::unique_ptr<plasticdeformerdata[]> m_datas;		  //!< (owned) The deformer datas array. One per mesh.</plasticdeformerdata[]>
Toshihiro Shimizu 890ddd
	std::vector<plastichandle> m_handles; //!< Source handles (emanated from skeleton vertices).</plastichandle>
Toshihiro Shimizu 890ddd
	std::vector<tpointd> m_dstHandles;	//!< Corresponding destination handle positions</tpointd>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int m_compiled; //!< Whether compiled data is present about a certain datatype.
Toshihiro Shimizu 890ddd
	int m_upToDate; //!< Whether updated  data is present about a certain datatype.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double m_outputFrame;	 //!< The frame of current output values.
Toshihiro Shimizu 890ddd
							  //!< Value numeric_limits::max can be used to invalidate
Toshihiro Shimizu 890ddd
							  //!< deformation outputs
Toshihiro Shimizu 890ddd
	TAffine m_skeletonAffine; //!< The skeleton affine applied to each handle.
Toshihiro Shimizu 890ddd
							  //!< In case it changes, the deformation is automatically recompiled.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double m_soMin, m_soMax;						//!< SO min and max across the whole group (useful while drawing
Toshihiro Shimizu 890ddd
													//!< due to the unboundedness of the SO parameter)
Toshihiro Shimizu 890ddd
	std::vector<std::pair<int, int="">> m_sortedFaces; //!< Pairs of face-mesh indices, by sorted stacking order.</std::pair<int,>
Toshihiro Shimizu 890ddd
													//!< This is the order that must be followed when drawing faces.
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	PlasticDeformerDataGroup();
Toshihiro Shimizu 890ddd
	~PlasticDeformerDataGroup();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	// Not copyable
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PlasticDeformerDataGroup(const PlasticDeformerDataGroup &);
Toshihiro Shimizu 890ddd
	PlasticDeformerDataGroup &operator=(const PlasticDeformerDataGroup &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//***********************************************************************************************
Toshihiro Shimizu 890ddd
//    PlasticDeformerStorage  declaration
Toshihiro Shimizu 890ddd
//***********************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! PlasticDeformerStorage is the global storage class for plastic deformers.
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  PlasticDeformer models a mesh-deformer object that can be used together with
Toshihiro Shimizu 890ddd
  texturing to create an interactive image-deformation technique. Direct use
Toshihiro Shimizu 890ddd
  of PlasticDeformer instances is discouraged, as they can be considered as
Toshihiro Shimizu 890ddd
  technical low-level interfaces to the deformation job.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
\par Rationale
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  The crucial reason behind the existance of this class lies in the
Toshihiro Shimizu 890ddd
  necessity to cache PlasticDeformer instances to achieve real-time speed in
Toshihiro Shimizu 890ddd
  the processing of part of its algorithms.
Toshihiro Shimizu 890ddd
  \n\n
Toshihiro Shimizu 890ddd
  In this context, caching is all about storing intermediate data so that they
Toshihiro Shimizu 890ddd
  are recalculated only when strictly necessary.
Toshihiro Shimizu 890ddd
  In PlasticDeformer's case, we can see 3 chained processing stages that need
Toshihiro Shimizu 890ddd
  to be calculated before the final result is produced:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \li  Initialization: <\B> A mesh is acquired
Toshihiro Shimizu 890ddd
  \li  Compilation: <\B> The deformation's source domain data is acquired
Toshihiro Shimizu 890ddd
  \li  Deformation: <\B> The deformation's destination domain data is acquired
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  Each step requires that the previous one has been computed. Obviously when,
Toshihiro Shimizu 890ddd
  say, only the deformation's destination data change, there is no need to process
Toshihiro Shimizu 890ddd
  the first 2 steps - their cached data remains valid.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
\par Interface
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  This class provides the preferential high-level interface to plastic deformers.
Toshihiro Shimizu 890ddd
  \n\n
Toshihiro Shimizu 890ddd
  The storage caches data about every requested deform specification, that is kept
Toshihiro Shimizu 890ddd
  until an explicit release command is issued. A data request is issued with a call
Toshihiro Shimizu 890ddd
  to the process() method, which accepts specification of a subset of deform-related
Toshihiro Shimizu 890ddd
  data to be returned, skipping unnecessary computations.
Toshihiro Shimizu 890ddd
  \n\n
Toshihiro Shimizu 890ddd
  The storage requires explicit content invalidation to know that is must
Toshihiro Shimizu 890ddd
  recalculate subsequent requests. Invalidation is specific to changes in a
Toshihiro Shimizu 890ddd
  PlasticSkeletonDeformation instance, and can be restrained to the destination
Toshihiro Shimizu 890ddd
  (deformed) domain, or require more expensive invalidation.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
\par Deformations and Data requests
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  Cached data is uniquely associated with pairs of meshImage and deformed skeletons,
Toshihiro Shimizu 890ddd
  meaning that the same meshImage can be deformed by multiple skeletons, and viceversa.
Toshihiro Shimizu 890ddd
  \n\n
Toshihiro Shimizu 890ddd
  A deformer data request needs an affine transform in input, which is intended to
Toshihiro Shimizu 890ddd
  map the skeleton deformation on top of the mesh (in mesh coordinates). The storage
Toshihiro Shimizu 890ddd
   does not <\I> store a PlasticDeformer instance for each different affine supplied,
Toshihiro Shimizu 890ddd
  but rather \a invalidates the old data in case it changes.
Toshihiro Shimizu 890ddd
  \n\n
Toshihiro Shimizu 890ddd
  The mesh vertex coordinates resulting from a deformation will be stored in the resulting
Toshihiro Shimizu 890ddd
  PlasticDeformerData::m_output member of each entry of the output array, one for each mesh
Toshihiro Shimizu 890ddd
  of the input meshImage. The returned coordinates are intended in the mesh reference.
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
\par Lifetime and Ownership
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  This class  does not claim ownerhip <\B> of neither the mesh nor the deformation that are
Toshihiro Shimizu 890ddd
  specified in a deformer request - and  lifetime tracking <\I> of the objects involved in
Toshihiro Shimizu 890ddd
  plastic deforming is a burden of callers.
Toshihiro Shimizu 890ddd
  \n\n
Toshihiro Shimizu 890ddd
  This class requires that the destruction of either a mesh or a deformation be signaled by a
Toshihiro Shimizu 890ddd
  call to the appropriate release method in order to enforce the associated deformers destruction.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \warning No call to the appropriate release method when either a mesh or a deformation which
Toshihiro Shimizu 890ddd
           has requested a deformer is destroyed \b will result in a \b leak.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class DVAPI PlasticDeformerStorage
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	class Imp;
Shinya Kitaoka 262a92
	std::unique_ptr<imp> m_imp;</imp>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	enum DataType {
Toshihiro Shimizu 890ddd
		NONE = 0x0,
Toshihiro Shimizu 890ddd
		HANDLES = 0x1, // Handles data
Toshihiro Shimizu 890ddd
		SO = 0x4,	  // Stacking Order data
Toshihiro Shimizu 890ddd
		MESH = 0x8,	// The deformed Mesh
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		ALL = HANDLES | SO | MESH
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	PlasticDeformerStorage();
Toshihiro Shimizu 890ddd
	~PlasticDeformerStorage();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	static PlasticDeformerStorage *instance();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! This function processes the specified meshImage-deformation pair, returning a DataGroup
Toshihiro Shimizu 890ddd
	//! with the required data.
Toshihiro Shimizu 890ddd
	/*!
Toshihiro Shimizu 890ddd
    \note This function \b caches all required data, so that subsequent requests about the same
Toshihiro Shimizu 890ddd
    triplet can be sped up considerably in case of cache match.
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
	const PlasticDeformerDataGroup *process(
Toshihiro Shimizu 890ddd
		double frame,
Toshihiro Shimizu 890ddd
		const TMeshImage *meshImage,
Toshihiro Shimizu 890ddd
		const PlasticSkeletonDeformation *deformation, int skeletonId,
Toshihiro Shimizu 890ddd
		const TAffine &deformationToMeshAffine,
Toshihiro Shimizu 890ddd
		DataType dataType = ALL);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! Performs the specified deformation once, \b without caching data.
Toshihiro Shimizu 890ddd
	/*!
Toshihiro Shimizu 890ddd
    This method allows the user to perform a single-shot Platic deformation, without dealing with
Toshihiro Shimizu 890ddd
    caching issues.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    \note Since caching is disabled, this method is comparably \a slower than its cached counterpart,
Toshihiro Shimizu 890ddd
          in case the same deformation is repeatedly invoked.
Toshihiro Shimizu 890ddd
          It is meant to be used only in absence of user interaction.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    \warning The returned pointer is owned by the \b caller, and must be manually deleted
Toshihiro Shimizu 890ddd
             when no longer needed.
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
	static const PlasticDeformerDataGroup *processOnce(
Toshihiro Shimizu 890ddd
		double frame,
Toshihiro Shimizu 890ddd
		const TMeshImage *meshImage,
Toshihiro Shimizu 890ddd
		const PlasticSkeletonDeformation *deformation, int skeletonId,
Toshihiro Shimizu 890ddd
		const TAffine &deformationToMeshAffine,
Toshihiro Shimizu 890ddd
		DataType dataType = ALL);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! Similarly to invalidateSkeleton(), for every deformer attached to the
Toshihiro Shimizu 890ddd
	//! specified mesh.
Toshihiro Shimizu 890ddd
	void invalidateMeshImage(const TMeshImage *meshImage,
Toshihiro Shimizu 890ddd
							 int recompiledDataType = NONE);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! Schedules all stored deformers associated to the specified deformation for
Toshihiro Shimizu 890ddd
	//! either re-deformation (stage 3 invalidation) or re-compilation (stage 2 invalidation).
Toshihiro Shimizu 890ddd
	/*!
Toshihiro Shimizu 890ddd
    Recompilation should be selected whenever the deformation has sustained source domain
Toshihiro Shimizu 890ddd
    changes, such as a vertex addition or removal, or when the \a source skeletal
Toshihiro Shimizu 890ddd
    configuration has changed.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    \note Recompilation is typically a slower process than the mere deformers update.
Toshihiro Shimizu 890ddd
    Select it explicitly only when it truly needs to be done.
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
	void invalidateSkeleton(
Toshihiro Shimizu 890ddd
		const PlasticSkeletonDeformation *deformation, int skeletonId,
Toshihiro Shimizu 890ddd
		int recompiledDataType = NONE);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! Similarly to invalidateSkeleton(), for everything attached to the
Toshihiro Shimizu 890ddd
	//! specified deformation.
Toshihiro Shimizu 890ddd
	void invalidateDeformation(
Toshihiro Shimizu 890ddd
		const PlasticSkeletonDeformation *deformation,
Toshihiro Shimizu 890ddd
		int recompiledDataType = NONE);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! Releases all deformers associated to the specified mesh image.
Toshihiro Shimizu 890ddd
	void releaseMeshData(const TMeshImage *meshImage);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! Releases all deformers associated to the specified skeletal deformation.
Toshihiro Shimizu 890ddd
	void releaseSkeletonData(const PlasticSkeletonDeformation *deformation, int skeletonId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! Releases all deformers associated to the specified skeletal deformation.
Toshihiro Shimizu 890ddd
	void releaseDeformationData(const PlasticSkeletonDeformation *deformation);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! Releases all deformers, effectively returning the storage to its empty state.
Toshihiro Shimizu 890ddd
	void clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	//! Retrieves the group of deformers (one per mesh in the image) associated to the input
Toshihiro Shimizu 890ddd
	//! pair, eventually creating one if none did exist.
Toshihiro Shimizu 890ddd
	PlasticDeformerDataGroup *deformerData(const TMeshImage *meshImage,
Toshihiro Shimizu 890ddd
										   const PlasticSkeletonDeformation *deformation, int skeletonId);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif // PLASTIDEFORMERSTORAGE_H