// // MeshPartPayload.h // interface/src/renderer // // Created by Sam Gateau on 10/3/15. // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef hifi_MeshPartPayload_h #define hifi_MeshPartPayload_h #include #include #include #include #include "Model.h" class Model; class MeshPartPayload { public: MeshPartPayload() {} MeshPartPayload(const std::shared_ptr& mesh, int partIndex, graphics::MaterialPointer material); typedef render::Payload Payload; typedef Payload::DataPointer Pointer; virtual void updateKey(bool isVisible, bool isLayered, uint8_t tagBits, bool isGroupCulled = false); virtual void updateMeshPart(const std::shared_ptr& drawMesh, int partIndex); virtual void notifyLocationChanged() {} void updateTransform(const Transform& transform, const Transform& offsetTransform); // Render Item interface virtual render::ItemKey getKey() const; virtual render::Item::Bound getBound() const; virtual render::ShapeKey getShapeKey() const; // shape interface virtual void render(RenderArgs* args); // ModelMeshPartPayload functions to perform render void drawCall(gpu::Batch& batch) const; virtual void bindMesh(gpu::Batch& batch); virtual void bindTransform(gpu::Batch& batch, RenderArgs::RenderMode renderMode) const; // Payload resource cached values Transform _drawTransform; Transform _transform; int _partIndex = 0; bool _hasColorAttrib { false }; graphics::Box _localBound; graphics::Box _adjustedLocalBound; mutable graphics::Box _worldBound; std::shared_ptr _drawMesh; graphics::MultiMaterial _drawMaterials; graphics::Mesh::Part _drawPart; size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; } size_t getMaterialTextureSize() { return _drawMaterials.top().material ? _drawMaterials.top().material->getTextureSize() : 0; } int getMaterialTextureCount() { return _drawMaterials.top().material ? _drawMaterials.top().material->getTextureCount() : 0; } bool hasTextureInfo() const { return _drawMaterials.top().material ? _drawMaterials.top().material->hasTextureInfo() : false; } void addMaterial(graphics::MaterialLayer material); void removeMaterial(graphics::MaterialPointer material); protected: render::ItemKey _itemKey{ render::ItemKey::Builder::opaqueShape().build() }; }; namespace render { template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload); template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload); template <> const ShapeKey shapeGetShapeKey(const MeshPartPayload::Pointer& payload); template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args); } class ModelMeshPartPayload : public MeshPartPayload { public: ModelMeshPartPayload(ModelPointer model, int meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform); typedef render::Payload Payload; typedef Payload::DataPointer Pointer; void notifyLocationChanged() override; void updateKey(bool isVisible, bool isLayered, uint8_t tagBits, bool isGroupCulled = false) override; // matrix palette skinning void updateClusterBuffer(const std::vector& clusterMatrices); // dual quaternion skinning void updateClusterBuffer(const std::vector& clusterDualQuaternions); void updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform); // Render Item interface int getLayer() const; render::ShapeKey getShapeKey() const override; // shape interface void render(RenderArgs* args) override; void setLayer(bool isLayeredInFront, bool isLayeredInHUD); void setShapeKey(bool invalidateShapeKey, bool isWireframe, bool useDualQuaternionSkinning); // ModelMeshPartPayload functions to perform render void bindMesh(gpu::Batch& batch) override; void bindTransform(gpu::Batch& batch, RenderArgs::RenderMode renderMode) const override; // matrix palette skinning void computeAdjustedLocalBound(const std::vector& clusterMatrices); // dual quaternion skinning void computeAdjustedLocalBound(const std::vector& clusterDualQuaternions); gpu::BufferPointer _clusterBuffer; enum class ClusterBufferType { Matrices, DualQuaternions }; ClusterBufferType _clusterBufferType { ClusterBufferType::Matrices }; int _meshIndex; int _shapeID; bool _isSkinned{ false }; bool _isBlendShaped { false }; bool _hasTangents { false }; private: void initCache(const ModelPointer& model); gpu::BufferPointer _blendedVertexBuffer; render::ShapeKey _shapeKey { render::ShapeKey::Builder::invalid() }; int _layer { render::Item::LAYER_3D }; }; namespace render { template <> const ItemKey payloadGetKey(const ModelMeshPartPayload::Pointer& payload); template <> const Item::Bound payloadGetBound(const ModelMeshPartPayload::Pointer& payload); template <> int payloadGetLayer(const ModelMeshPartPayload::Pointer& payload); template <> const ShapeKey shapeGetShapeKey(const ModelMeshPartPayload::Pointer& payload); template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, RenderArgs* args); } #endif // hifi_MeshPartPayload_h