From 21d4d42825ab79a8d0d113c270bf7c8a45d033bf Mon Sep 17 00:00:00 2001 From: James Chen Date: Fri, 15 Nov 2024 16:48:09 +0800 Subject: [PATCH] Fix Model::setInstancedAttribute and SubModule::setInstancedAttribute. --- .../bindings/manual/jsb_scene_manual.cpp | 40 ++++------------- native/cocos/scene/Model.cpp | 4 +- native/cocos/scene/Model.h | 2 +- native/cocos/scene/SubModel.cpp | 45 +------------------ native/cocos/scene/SubModel.h | 2 +- 5 files changed, 15 insertions(+), 78 deletions(-) diff --git a/native/cocos/bindings/manual/jsb_scene_manual.cpp b/native/cocos/bindings/manual/jsb_scene_manual.cpp index 4dba7ef5ffc..a3474c44a3b 100644 --- a/native/cocos/bindings/manual/jsb_scene_manual.cpp +++ b/native/cocos/bindings/manual/jsb_scene_manual.cpp @@ -677,48 +677,26 @@ static bool js_Model_setInstancedAttribute(se::State &s) // NOLINT(readability-i if (val.toObject()->isArray()) { uint32_t len = 0; val.toObject()->getArrayLength(&len); + + cc::Float32Array value(len); se::Value dataVal; - ccstd::array stackData; - float *pData = nullptr; - bool needFree = false; - - if (len <= static_cast(stackData.size())) { - pData = stackData.data(); - } else { - pData = static_cast(CC_MALLOC(len)); - needFree = true; - } - for (uint32_t i = 0; i < len; ++i) { ok = val.toObject()->getArrayElement(i, &dataVal); CC_ASSERT(ok && dataVal.isNumber()); - pData[i] = dataVal.toFloat(); + value[i] = dataVal.toFloat(); } - cobj->setInstancedAttribute(name, pData, len); - - if (needFree) { - CC_FREE(pData); - } + cobj->setInstancedAttribute(name, value); return true; } if (val.toObject()->isTypedArray()) { - se::Object::TypedArrayType type = val.toObject()->getTypedArrayType(); - switch (type) { - case se::Object::TypedArrayType::FLOAT32: { - uint8_t *data = nullptr; - size_t byteCount = 0; - if (val.toObject()->getTypedArrayData(&data, &byteCount) && data != nullptr && byteCount > 0) { - cobj->setInstancedAttribute(name, reinterpret_cast(data), static_cast(byteCount)); - } - } break; - - default: - // FIXME: - CC_ABORT(); - break; + cc::TypedArray arr; + ok = sevalue_to_native(val, &arr); + SE_PRECONDITION2(ok, false, "Error processing arguments"); + if (ok) { + cobj->setInstancedAttribute(name, arr); } return true; } diff --git a/native/cocos/scene/Model.cpp b/native/cocos/scene/Model.cpp index 1d88206711e..4f9ef50393f 100644 --- a/native/cocos/scene/Model.cpp +++ b/native/cocos/scene/Model.cpp @@ -707,9 +707,9 @@ void Model::updateReflectionProbeId() { _localDataUpdated = true; } -void Model::setInstancedAttribute(const ccstd::string &name, const float *value, uint32_t byteCount) { +void Model::setInstancedAttribute(const ccstd::string &name, const TypedArray &value) { for (const auto &subModel : _subModels) { - subModel->setInstancedAttribute(name, value, byteCount); + subModel->setInstancedAttribute(name, value); } } void Model::setReflectionProbeType(UseReflectionProbeType val) { diff --git a/native/cocos/scene/Model.h b/native/cocos/scene/Model.h index 015a3ace526..ec334533051 100644 --- a/native/cocos/scene/Model.h +++ b/native/cocos/scene/Model.h @@ -135,7 +135,7 @@ class Model : public RefCounted { void onMacroPatchesStateChanged(); void onGeometryChanged(); void setSubModelMesh(index_t idx, RenderingSubMesh *subMesh) const; - void setInstancedAttribute(const ccstd::string &name, const float *value, uint32_t byteCount); + void setInstancedAttribute(const ccstd::string &name, const TypedArray &value); void updateWorldBound(); void updateWorldBoundsForJSSkinningModel(const Vec3 &min, const Vec3 &max); void updateWorldBoundsForJSBakedSkinningModel(geometry::AABB *aabb); diff --git a/native/cocos/scene/SubModel.cpp b/native/cocos/scene/SubModel.cpp index fab9bb1961e..652687d2d2d 100644 --- a/native/cocos/scene/SubModel.cpp +++ b/native/cocos/scene/SubModel.cpp @@ -362,48 +362,7 @@ void SubModel::setSubMesh(RenderingSubMesh *subMesh) { _subMesh = subMesh; } -template -void copyInstancedData(const T& view, const float* value, uint32_t byteCount) { - auto* dstData = view.buffer()->getData() + view.byteOffset(); - uint32_t bLength; - if constexpr (std::is_same_v) { - bLength = byteCount * sizeof(float_t); - } else if constexpr (std::is_same_v) { - bLength = byteCount * sizeof(uint16_t); - } else if constexpr (std::is_same_v) { - bLength = byteCount * sizeof(int16_t); - } else if constexpr (std::is_same_v) { - bLength = byteCount * sizeof(uint32_t); - } else if constexpr (std::is_same_v) { - bLength = byteCount * sizeof(int32_t); - } else if constexpr (std::is_same_v) { - bLength = byteCount * sizeof(uint8_t); - } else if constexpr (std::is_same_v) { - bLength = byteCount * sizeof(int8_t); - } - CC_ASSERT(bLength <= view.byteLength()); - memcpy(dstData, value, bLength); -} - -void handleTypedArray(const cc::TypedArray& view, const float* value, uint32_t byteCount) { - if (ccstd::holds_alternative(view)) { - copyInstancedData(ccstd::get(view), value, byteCount); - } else if (ccstd::holds_alternative(view)) { - copyInstancedData(ccstd::get(view), value, byteCount); - } else if (ccstd::holds_alternative(view)) { - copyInstancedData(ccstd::get(view), value, byteCount); - } else if (ccstd::holds_alternative(view)) { - copyInstancedData(ccstd::get(view), value, byteCount); - } else if (ccstd::holds_alternative(view)) { - copyInstancedData(ccstd::get(view), value, byteCount); - } else if (ccstd::holds_alternative(view)) { - copyInstancedData(ccstd::get(view), value, byteCount); - } else if (ccstd::holds_alternative(view)) { - copyInstancedData(ccstd::get(view), value, byteCount); - } -} - -void SubModel::setInstancedAttribute(const ccstd::string &name, const float *value, uint32_t byteCount) { +void SubModel::setInstancedAttribute(const ccstd::string &name, const TypedArray &value) { const auto &attributes = _instancedAttributeBlock.attributes; auto &views = _instancedAttributeBlock.views; for (size_t i = 0, len = attributes.size(); i < len; ++i) { @@ -417,7 +376,7 @@ void SubModel::setInstancedAttribute(const ccstd::string &name, const float *val case gfx::FormatType::INT: case gfx::FormatType::FLOAT: case gfx::FormatType::UFLOAT: { - handleTypedArray(views[i], value, byteCount); + copyTypedArray(views[i], 0, value); } break; case gfx::FormatType::NONE: default: diff --git a/native/cocos/scene/SubModel.h b/native/cocos/scene/SubModel.h index a8e595f4d3b..780ff53ded7 100644 --- a/native/cocos/scene/SubModel.h +++ b/native/cocos/scene/SubModel.h @@ -66,7 +66,7 @@ class SubModel : public RefCounted { void setSubMesh(RenderingSubMesh *subMesh); inline void setInstancedWorldMatrixIndex(int32_t worldMatrixIndex) { _instancedWorldMatrixIndex = worldMatrixIndex; } inline void setInstancedSHIndex(int32_t index) { _instancedSHIndex = index; } - void setInstancedAttribute(const ccstd::string &name, const float *value, uint32_t byteCount); + void setInstancedAttribute(const ccstd::string &name, const TypedArray &value); inline gfx::DescriptorSet *getDescriptorSet() const { return _descriptorSet; } inline gfx::DescriptorSet *getWorldBoundDescriptorSet() const { return _worldBoundDescriptorSet; }