Skip to content

Commit

Permalink
setInstancedAttribute
Browse files Browse the repository at this point in the history
  • Loading branch information
GengineJS committed Nov 14, 2024
1 parent acbd759 commit 559c119
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 18 deletions.
8 changes: 4 additions & 4 deletions native/cocos/bindings/manual/jsb_scene_manual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ static bool js_Model_setInstancedAttribute(se::State &s) // NOLINT(readability-i
pData[i] = dataVal.toFloat();
}

cobj->setInstancedAttribute(name, pData, len * sizeof(float));
cobj->setInstancedAttribute(name, pData, len);

if (needFree) {
CC_FREE(pData);
Expand All @@ -709,9 +709,9 @@ static bool js_Model_setInstancedAttribute(se::State &s) // NOLINT(readability-i
switch (type) {
case se::Object::TypedArrayType::FLOAT32: {
uint8_t *data = nullptr;
size_t byteLength = 0;
if (val.toObject()->getTypedArrayData(&data, &byteLength) && data != nullptr && byteLength > 0) {
cobj->setInstancedAttribute(name, reinterpret_cast<const float *>(data), static_cast<uint32_t>(byteLength));
size_t byteCount = 0;
if (val.toObject()->getTypedArrayData(&data, &byteCount) && data != nullptr && byteCount > 0) {
cobj->setInstancedAttribute(name, reinterpret_cast<const float *>(data), static_cast<uint32_t>(byteCount));
}
} break;

Expand Down
4 changes: 2 additions & 2 deletions native/cocos/scene/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -707,9 +707,9 @@ void Model::updateReflectionProbeId() {
_localDataUpdated = true;
}

void Model::setInstancedAttribute(const ccstd::string &name, const float *value, uint32_t byteLength) {
void Model::setInstancedAttribute(const ccstd::string &name, const float *value, uint32_t byteCount) {
for (const auto &subModel : _subModels) {
subModel->setInstancedAttribute(name, value, byteLength);
subModel->setInstancedAttribute(name, value, byteCount);
}
}
void Model::setReflectionProbeType(UseReflectionProbeType val) {
Expand Down
2 changes: 1 addition & 1 deletion native/cocos/scene/Model.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 byteLength);
void setInstancedAttribute(const ccstd::string &name, const float *value, uint32_t byteCount);
void updateWorldBound();
void updateWorldBoundsForJSSkinningModel(const Vec3 &min, const Vec3 &max);
void updateWorldBoundsForJSBakedSkinningModel(geometry::AABB *aabb);
Expand Down
56 changes: 46 additions & 10 deletions native/cocos/scene/SubModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,30 +362,66 @@ void SubModel::setSubMesh(RenderingSubMesh *subMesh) {
_subMesh = subMesh;
}

void SubModel::setInstancedAttribute(const ccstd::string &name, const float *value, uint32_t byteLength) {
template<typename T>
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<T, Float32Array>) {
bLength = byteCount * sizeof(float_t);
} else if constexpr (std::is_same_v<T, Uint16Array>) {
bLength = byteCount * sizeof(uint16_t);
} else if constexpr (std::is_same_v<T, Int16Array>) {
bLength = byteCount * sizeof(int16_t);
} else if constexpr (std::is_same_v<T, Uint32Array>) {
bLength = byteCount * sizeof(uint32_t);
} else if constexpr (std::is_same_v<T, Int32Array>) {
bLength = byteCount * sizeof(int32_t);
} else if constexpr (std::is_same_v<T, Uint8Array>) {
bLength = byteCount * sizeof(uint8_t);
} else if constexpr (std::is_same_v<T, Int8Array>) {
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<Float32Array>(view)) {
copyInstancedData(ccstd::get<Float32Array>(view), value, byteCount);
} else if (ccstd::holds_alternative<Uint16Array>(view)) {
copyInstancedData(ccstd::get<Uint16Array>(view), value, byteCount);
} else if (ccstd::holds_alternative<Int16Array>(view)) {
copyInstancedData(ccstd::get<Int16Array>(view), value, byteCount);
} else if (ccstd::holds_alternative<Uint32Array>(view)) {
copyInstancedData(ccstd::get<Uint32Array>(view), value, byteCount);
} else if (ccstd::holds_alternative<Int32Array>(view)) {
copyInstancedData(ccstd::get<Int32Array>(view), value, byteCount);
} else if (ccstd::holds_alternative<Uint8Array>(view)) {
copyInstancedData(ccstd::get<Uint8Array>(view), value, byteCount);
} else if (ccstd::holds_alternative<Int8Array>(view)) {
copyInstancedData(ccstd::get<Int8Array>(view), value, byteCount);
}
}

void SubModel::setInstancedAttribute(const ccstd::string &name, const float *value, uint32_t byteCount) {
const auto &attributes = _instancedAttributeBlock.attributes;
auto &views = _instancedAttributeBlock.views;
for (size_t i = 0, len = attributes.size(); i < len; ++i) {
const auto &attribute = attributes[i];
if (attribute.name == name) {
const auto &info = gfx::GFX_FORMAT_INFOS[static_cast<uint32_t>(attribute.format)];
switch (info.type) {
case gfx::FormatType::NONE:
case gfx::FormatType::UNORM:
case gfx::FormatType::SNORM:
case gfx::FormatType::UINT:
case gfx::FormatType::INT: {
CC_ABORT();
} break;
case gfx::FormatType::INT:
case gfx::FormatType::FLOAT:
case gfx::FormatType::UFLOAT: {
CC_ASSERT(ccstd::holds_alternative<Float32Array>(views[i]));
auto &view = ccstd::get<Float32Array>(views[i]);
auto *dstData = reinterpret_cast<float *>(view.buffer()->getData() + view.byteOffset());
CC_ASSERT(byteLength <= view.byteLength());
memcpy(dstData, value, byteLength);
handleTypedArray(views[i], value, byteCount);
} break;
case gfx::FormatType::NONE:
default:
CC_ABORT();
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion native/cocos/scene/SubModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 byteLength);
void setInstancedAttribute(const ccstd::string &name, const float *value, uint32_t byteCount);

inline gfx::DescriptorSet *getDescriptorSet() const { return _descriptorSet; }
inline gfx::DescriptorSet *getWorldBoundDescriptorSet() const { return _worldBoundDescriptorSet; }
Expand Down

0 comments on commit 559c119

Please sign in to comment.