Shinya Kitaoka 810553
#pragma once
Shinya Kitaoka 810553
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
Shinya Kitaoka 120a6e
//! PlasticDeformerData contains all the data needed to perform the deformation
Shinya Kitaoka 120a6e
//! of a single mesh.
Toshihiro Shimizu 890ddd
struct DVAPI PlasticDeformerData {
Shinya Kitaoka 120a6e
  PlasticDeformer m_deformer;  //!< The mesh deformer itself
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::unique_ptr<double[]> m_so;      //!< (owned) Faces' stacking order</double[]>
Shinya Kitaoka 120a6e
  std::unique_ptr<double[]> m_output;  //!< (owned) Output vertex coordinates</double[]>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<int> m_faceHints;  //!< Handles' face hints</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PlasticDeformerData();
Shinya Kitaoka 120a6e
  ~PlasticDeformerData();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // Not copyable
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  PlasticDeformerData(const PlasticDeformerData &);
Shinya Kitaoka 120a6e
  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 120a6e
  std::unique_ptr<plasticdeformerdata[]></plasticdeformerdata[]>
Shinya Kitaoka 120a6e
      m_datas;  //!< (owned) The deformer datas array. One per mesh.
Shinya Kitaoka 120a6e
  std::vector<plastichandle></plastichandle>
Shinya Kitaoka 120a6e
      m_handles;  //!< Source handles (emanated from skeleton vertices).
Shinya Kitaoka 120a6e
  std::vector<tpointd></tpointd>
Shinya Kitaoka 120a6e
      m_dstHandles;  //!< Corresponding destination handle positions
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int m_compiled;  //!< Whether compiled data is present about a certain
Shinya Kitaoka 38fd86
                   //! datatype.
Shinya Kitaoka 120a6e
  int m_upToDate;  //!< Whether updated  data is present about a certain
Shinya Kitaoka 38fd86
                   //! datatype.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double m_outputFrame;  //!< The frame of current output values.
Shinya Kitaoka 120a6e
  //!< Value numeric_limits::max can be used to invalidate
Shinya Kitaoka 120a6e
  //!< deformation outputs
Shinya Kitaoka 120a6e
  TAffine m_skeletonAffine;  //!< The skeleton affine applied to each handle.
Shinya Kitaoka 120a6e
  //!< In case it changes, the deformation is automatically recompiled.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double m_soMin,
Shinya Kitaoka 120a6e
      m_soMax;  //!< SO min and max across the whole group (useful while drawing
Shinya Kitaoka 120a6e
                //!< due to the unboundedness of the SO parameter)
Shinya Kitaoka 120a6e
  std::vector<std::pair<int, int="">></std::pair<int,>
Shinya Kitaoka 120a6e
      m_sortedFaces;  //!< Pairs of face-mesh indices, by sorted stacking order.
Shinya Kitaoka 120a6e
  //!< This is the order that must be followed when drawing faces.
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PlasticDeformerDataGroup();
Shinya Kitaoka 120a6e
  ~PlasticDeformerDataGroup();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // Not copyable
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  PlasticDeformerDataGroup(const PlasticDeformerDataGroup &);
Shinya Kitaoka 120a6e
  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
Shinya Kitaoka 120a6e
  \li  Deformation: <\B> The deformation's destination domain data is
Shinya Kitaoka 120a6e
acquired
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  Each step requires that the previous one has been computed. Obviously when,
Shinya Kitaoka 120a6e
  say, only the deformation's destination data change, there is no need to
Shinya Kitaoka 120a6e
process
Toshihiro Shimizu 890ddd
  the first 2 steps - their cached data remains valid.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
\par Interface
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  This class provides the preferential high-level interface to plastic
Shinya Kitaoka 120a6e
deformers.
Toshihiro Shimizu 890ddd
  \n\n
Shinya Kitaoka 120a6e
  The storage caches data about every requested deform specification, that is
Shinya Kitaoka 120a6e
kept
Shinya Kitaoka 120a6e
  until an explicit release command is issued. A data request is issued with a
Shinya Kitaoka 120a6e
call
Shinya Kitaoka 120a6e
  to the process() method, which accepts specification of a subset of
Shinya Kitaoka 120a6e
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
Shinya Kitaoka 120a6e
  Cached data is uniquely associated with pairs of meshImage and deformed
Shinya Kitaoka 120a6e
skeletons,
Shinya Kitaoka 120a6e
  meaning that the same meshImage can be deformed by multiple skeletons, and
Shinya Kitaoka 120a6e
viceversa.
Toshihiro Shimizu 890ddd
  \n\n
Shinya Kitaoka 120a6e
  A deformer data request needs an affine transform in input, which is intended
Shinya Kitaoka 120a6e
to
Shinya Kitaoka 120a6e
  map the skeleton deformation on top of the mesh (in mesh coordinates). The
Shinya Kitaoka 120a6e
storage
Shinya Kitaoka 120a6e
   does not <\I> store a PlasticDeformer instance for each different affine
Shinya Kitaoka 120a6e
supplied,
Toshihiro Shimizu 890ddd
  but rather \a invalidates the old data in case it changes.
Toshihiro Shimizu 890ddd
  \n\n
Shinya Kitaoka 120a6e
  The mesh vertex coordinates resulting from a deformation will be stored in the
Shinya Kitaoka 120a6e
resulting
Shinya Kitaoka 120a6e
  PlasticDeformerData::m_output member of each entry of the output array, one
Shinya Kitaoka 120a6e
for each mesh
Shinya Kitaoka 120a6e
  of the input meshImage. The returned coordinates are intended in the mesh
Shinya Kitaoka 120a6e
reference.
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
\par Lifetime and Ownership
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  This class  does not claim ownerhip <\B> of neither the mesh nor the
Shinya Kitaoka 120a6e
deformation that are
Shinya Kitaoka 120a6e
  specified in a deformer request - and  lifetime tracking <\I> of the
Shinya Kitaoka 120a6e
objects involved in
Toshihiro Shimizu 890ddd
  plastic deforming is a burden of callers.
Toshihiro Shimizu 890ddd
  \n\n
Shinya Kitaoka 120a6e
  This class requires that the destruction of either a mesh or a deformation be
Shinya Kitaoka 120a6e
signaled by a
Shinya Kitaoka 120a6e
  call to the appropriate release method in order to enforce the associated
Shinya Kitaoka 120a6e
deformers destruction.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  \warning No call to the appropriate release method when either a mesh or a
Shinya Kitaoka 120a6e
deformation which
Toshihiro Shimizu 890ddd
           has requested a deformer is destroyed \b will result in a \b leak.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class DVAPI PlasticDeformerStorage {
Shinya Kitaoka 120a6e
  class Imp;
Shinya Kitaoka 120a6e
  std::unique_ptr<imp> m_imp;</imp>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  enum DataType {
Shinya Kitaoka 120a6e
    NONE    = 0x0,
Shinya Kitaoka 120a6e
    HANDLES = 0x1,  // Handles data
Shinya Kitaoka 120a6e
    SO      = 0x4,  // Stacking Order data
Shinya Kitaoka 120a6e
    MESH    = 0x8,  // The deformed Mesh
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ALL = HANDLES | SO | MESH
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PlasticDeformerStorage();
Shinya Kitaoka 120a6e
  ~PlasticDeformerStorage();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  static PlasticDeformerStorage *instance();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! This function processes the specified meshImage-deformation pair,
Shinya Kitaoka 120a6e
  //! returning a DataGroup
Shinya Kitaoka 120a6e
  //! with the required data.
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
\note This function \b caches all required data, so that subsequent requests
Shinya Kitaoka 120a6e
about the same
Shinya Kitaoka 120a6e
triplet can be sped up considerably in case of cache match.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  const PlasticDeformerDataGroup *process(
Shinya Kitaoka 120a6e
      double frame, const TMeshImage *meshImage,
Shinya Kitaoka 120a6e
      const PlasticSkeletonDeformation *deformation, int skeletonId,
Shinya Kitaoka 120a6e
      const TAffine &deformationToMeshAffine, DataType dataType = ALL);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Performs the specified deformation once, \b without caching data.
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
This method allows the user to perform a single-shot Platic deformation, without
Shinya Kitaoka 120a6e
dealing with
Shinya Kitaoka 120a6e
caching issues.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
\note Since caching is disabled, this method is comparably \a slower than its
Shinya Kitaoka 120a6e
cached counterpart,
Shinya Kitaoka 120a6e
    in case the same deformation is repeatedly invoked.
Shinya Kitaoka 120a6e
    It is meant to be used only in absence of user interaction.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
\warning The returned pointer is owned by the \b caller, and must be manually
Shinya Kitaoka 120a6e
deleted
Shinya Kitaoka 120a6e
       when no longer needed.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  static const PlasticDeformerDataGroup *processOnce(
Shinya Kitaoka 120a6e
      double frame, const TMeshImage *meshImage,
Shinya Kitaoka 120a6e
      const PlasticSkeletonDeformation *deformation, int skeletonId,
Shinya Kitaoka 120a6e
      const TAffine &deformationToMeshAffine, DataType dataType = ALL);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Similarly to invalidateSkeleton(), for every deformer attached to the
Shinya Kitaoka 120a6e
  //! specified mesh.
Shinya Kitaoka 120a6e
  void invalidateMeshImage(const TMeshImage *meshImage,
Shinya Kitaoka 120a6e
                           int recompiledDataType = NONE);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Schedules all stored deformers associated to the specified deformation for
Shinya Kitaoka 120a6e
  //! either re-deformation (stage 3 invalidation) or re-compilation (stage 2
Shinya Kitaoka 120a6e
  //! invalidation).
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
Recompilation should be selected whenever the deformation has sustained source
Shinya Kitaoka 120a6e
domain
Shinya Kitaoka 120a6e
changes, such as a vertex addition or removal, or when the \a source skeletal
Shinya Kitaoka 120a6e
configuration has changed.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
\note Recompilation is typically a slower process than the mere deformers
Shinya Kitaoka 120a6e
update.
Shinya Kitaoka 120a6e
Select it explicitly only when it truly needs to be done.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  void invalidateSkeleton(const PlasticSkeletonDeformation *deformation,
Shinya Kitaoka 120a6e
                          int skeletonId, int recompiledDataType = NONE);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Similarly to invalidateSkeleton(), for everything attached to the
Shinya Kitaoka 120a6e
  //! specified deformation.
Shinya Kitaoka 120a6e
  void invalidateDeformation(const PlasticSkeletonDeformation *deformation,
Shinya Kitaoka 120a6e
                             int recompiledDataType = NONE);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Releases all deformers associated to the specified mesh image.
Shinya Kitaoka 120a6e
  void releaseMeshData(const TMeshImage *meshImage);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Releases all deformers associated to the specified skeletal deformation.
Shinya Kitaoka 120a6e
  void releaseSkeletonData(const PlasticSkeletonDeformation *deformation,
Shinya Kitaoka 120a6e
                           int skeletonId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Releases all deformers associated to the specified skeletal deformation.
Shinya Kitaoka 120a6e
  void releaseDeformationData(const PlasticSkeletonDeformation *deformation);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Releases all deformers, effectively returning the storage to its empty
Shinya Kitaoka 120a6e
  //! state.
Shinya Kitaoka 120a6e
  void clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  //! Retrieves the group of deformers (one per mesh in the image) associated to
Shinya Kitaoka 120a6e
  //! the input
Shinya Kitaoka 120a6e
  //! pair, eventually creating one if none did exist.
Shinya Kitaoka 120a6e
  PlasticDeformerDataGroup *deformerData(
Shinya Kitaoka 120a6e
      const TMeshImage *meshImage,
Shinya Kitaoka 120a6e
      const PlasticSkeletonDeformation *deformation, int skeletonId);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // PLASTIDEFORMERSTORAGE_H