// // Copyright 2016 Pixar // // Licensed under the Apache License, Version 2.0 (the "Apache License") // with the following modification; you may not use this file except in // compliance with the Apache License and the following modification to it: // Section 6. Trademarks. is deleted and replaced with: // // 6. Trademarks. This License does not grant permission to use the trade // names, trademarks, service marks, or product names of the Licensor // and its affiliates, except as required to comply with Section 4(c) of // the License and to reproduce the content of the NOTICE file. // // You may obtain a copy of the Apache License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the Apache License with the above modification is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // #ifndef PXR_IMAGING_PLUGIN_HD_EMBREE_INSTANCER_H #define PXR_IMAGING_PLUGIN_HD_EMBREE_INSTANCER_H #include "pxr/pxr.h" #include "pxr/imaging/hd/instancer.h" #include "pxr/imaging/hd/vtBufferSource.h" #include "pxr/base/tf/hashmap.h" #include "pxr/base/tf/token.h" #include PXR_NAMESPACE_OPEN_SCOPE /// \class HdEmbreeInstancer /// /// HdEmbree implements instancing by adding prototype geometry to the BVH /// multiple times within HdEmbreeMesh::Sync(). The only instance-varying /// attribute that HdEmbree supports is transform, so the natural /// accessor to instancer data is ComputeInstanceTransforms(), /// which returns a list of transforms to apply to the given prototype /// (one instance per transform). /// /// Nested instancing can be handled by recursion, and by taking the /// cartesian product of the transform arrays at each nesting level, to /// create a flattened transform array. /// class HdEmbreeInstancer : public HdInstancer { public: /// Constructor. /// \param delegate The scene delegate backing this instancer's data. /// \param id The unique id of this instancer. /// \param parentInstancerId The unique id of the parent instancer, /// or an empty id if not applicable. HdEmbreeInstancer(HdSceneDelegate* delegate, SdfPath const& id, SdfPath const &parentInstancerId); /// Destructor. ~HdEmbreeInstancer(); /// Computes all instance transforms for the provided prototype id, /// taking into account the scene delegate's instancerTransform and the /// instance primvars "instanceTransform", "translate", "rotate", "scale". /// Computes and flattens nested transforms, if necessary. /// \param prototypeId The prototype to compute transforms for. /// \return One transform per instance, to apply when drawing. VtMatrix4dArray ComputeInstanceTransforms(SdfPath const &prototypeId); private: // Checks the change tracker to determine whether instance primvars are // dirty, and if so pulls them. Since primvars can only be pulled once, // and are cached, this function is not re-entrant. However, this function // is called by ComputeInstanceTransforms, which is called (potentially) // by HdEmbreeMesh::Sync(), which is dispatched in parallel, so it needs // to be guarded by _instanceLock. // // Pulled primvars are cached in _primvarMap. void _SyncPrimvars(); // Mutex guard for _SyncPrimvars(). std::mutex _instanceLock; // Map of the latest primvar data for this instancer, keyed by // primvar name. Primvar values are VtValue, an any-type; they are // interpreted at consumption time (here, in ComputeInstanceTransforms). TfHashMap _primvarMap; }; PXR_NAMESPACE_CLOSE_SCOPE #endif // PXR_IMAGING_PLUGIN_HD_EMBREE_INSTANCER_H