From bd8a6acab1c215045ab126c54189188029d78e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 17 Jun 2024 07:33:25 +0200 Subject: [PATCH] fix: MaterialInstance API (#204) There were some differences between the TS types and the native methods. This PR also aligned MaterialInstance implementation with the Material implementation. --- package/cpp/core/RNFMaterialImpl.cpp | 16 +-- .../cpp/core/RNFMaterialInstanceWrapper.cpp | 134 ++++++++++++++++-- package/cpp/core/RNFMaterialInstanceWrapper.h | 12 +- package/cpp/core/RNFMaterialWrapper.cpp | 10 +- package/src/types/MaterialInstance.ts | 18 ++- 5 files changed, 155 insertions(+), 35 deletions(-) diff --git a/package/cpp/core/RNFMaterialImpl.cpp b/package/cpp/core/RNFMaterialImpl.cpp index 701c7bc4..f826c615 100644 --- a/package/cpp/core/RNFMaterialImpl.cpp +++ b/package/cpp/core/RNFMaterialImpl.cpp @@ -30,7 +30,7 @@ void MaterialImpl::setDefaultFloatParameter(std::string name, double value) { std::unique_lock lock(_mutex); if (!_material->hasParameter(name.c_str())) { - throw std::runtime_error("MaterialWrapper::setDefaultFloatParameter: Material does not have parameter \"" + name + "\"!"); + throw std::runtime_error("MaterialWrapper::setFloatParameter: Material does not have parameter \"" + name + "\"!"); } _material->setDefaultParameter(name.c_str(), (float)value); @@ -40,7 +40,7 @@ void MaterialImpl::setDefaultIntParameter(std::string name, int value) { std::unique_lock lock(_mutex); if (!_material->hasParameter(name.c_str())) { - throw std::runtime_error("MaterialWrapper::setDefaultIntParameter: Material does not have parameter \"" + name + "\"!"); + throw std::runtime_error("MaterialWrapper::setIntParameter: Material does not have parameter \"" + name + "\"!"); } _material->setDefaultParameter(name.c_str(), value); @@ -59,11 +59,11 @@ void MaterialImpl::setDefaultTextureParameter(std::string name, Texture* texture void MaterialImpl::setDefaultFloat3Parameter(std::string name, std::vector vector) { std::unique_lock lock(_mutex); if (vector.size() != 3) { - throw std::runtime_error("setDefaultFloat3Parameter: RGB vector must have 3 elements!"); + throw std::runtime_error("setFloat3Parameter: RGB vector must have 3 elements!"); } if (!_material->hasParameter(name.c_str())) { - throw std::runtime_error("setDefaultFloat3Parameter: Material does not have parameter \"" + name + "\"!"); + throw std::runtime_error("setFloat3Parameter: Material does not have parameter \"" + name + "\"!"); } float x = vector[0]; @@ -76,11 +76,11 @@ void MaterialImpl::setDefaultFloat3Parameter(std::string name, std::vector vector) { std::unique_lock lock(_mutex); if (vector.size() != 4) { - throw std::runtime_error("setDefaultFloat4Parameter: RGBA vector must have 4 elements!"); + throw std::runtime_error("setFloat4Parameter: RGBA vector must have 4 elements!"); } if (!_material->hasParameter(name.c_str())) { - throw std::runtime_error("setDefaultFloat4Parameter: Material does not have parameter \"" + name + "\"!"); + throw std::runtime_error("setFloat4Parameter: Material does not have parameter \"" + name + "\"!"); } double r = vector[0]; @@ -99,11 +99,11 @@ void MaterialImpl::setDefaultMat3fParameter(std::string name, std::vectorhasParameter(name.c_str())) { - throw std::runtime_error("MaterialWrapper::setDefaultMat3fParameter: Material does not have parameter \"" + name + "\"!"); + throw std::runtime_error("MaterialWrapper::setMat3fParameter: Material does not have parameter \"" + name + "\"!"); } if (value.size() != 9) { - throw std::runtime_error("MaterialWrapper::setDefaultMat3fParameter: Value vector must have 9 elements!"); + throw std::runtime_error("MaterialWrapper::setMat3fParameter: Value vector must have 9 elements!"); } math::mat3f matrix = math::mat3f((float)value[0], (float)value[1], (float)value[2], (float)value[3], (float)value[4], (float)value[5], diff --git a/package/cpp/core/RNFMaterialInstanceWrapper.cpp b/package/cpp/core/RNFMaterialInstanceWrapper.cpp index 06b6c62a..79fd433d 100644 --- a/package/cpp/core/RNFMaterialInstanceWrapper.cpp +++ b/package/cpp/core/RNFMaterialInstanceWrapper.cpp @@ -6,14 +6,23 @@ #include "RNFCullingModeEnum.h" #include "RNFTransparencyModeEnum.h" #include +#include namespace margelo { void MaterialInstanceWrapper::loadHybridMethods() { registerHybridMethod("setCullingMode", &MaterialInstanceWrapper::setCullingMode, this); registerHybridMethod("setTransparencyMode", &MaterialInstanceWrapper::setTransparencyMode, this); registerHybridMethod("changeAlpha", &MaterialInstanceWrapper::changeAlpha, this); - registerHybridMethod("setParameter", &MaterialInstanceWrapper::setParameter, this); - registerHybridMethod("setDefaultFloat4Parameter", &MaterialInstanceWrapper::setBaseColorSRGB, this); + registerHybridMethod("setFloat4Parameter", &MaterialInstanceWrapper::setFloatParameter, this); + registerHybridMethod("setIntParameter", &MaterialInstanceWrapper::setIntParameter, this); + registerHybridMethod("setFloat3Parameter", &MaterialInstanceWrapper::setFloat3Parameter, this); + registerHybridMethod("setFloat4Parameter", &MaterialInstanceWrapper::setFloat4Parameter, this); + registerHybridMethod("setMat3fParameter", &MaterialInstanceWrapper::setMat3fParameter, this); + registerHybridMethod("getFloatParameter", &MaterialInstanceWrapper::getFloatParameter, this); + registerHybridMethod("getIntParameter", &MaterialInstanceWrapper::getIntParameter, this); + registerHybridMethod("getFloat3Parameter", &MaterialInstanceWrapper::getFloat3Parameter, this); + registerHybridMethod("getFloat4Parameter", &MaterialInstanceWrapper::getFloat4Parameter, this); + registerHybridMethod("getMat3fParameter", &MaterialInstanceWrapper::getMat3fParameter, this); registerHybridGetter("getName", &MaterialInstanceWrapper::getName, this); } @@ -50,31 +59,80 @@ void MaterialInstanceWrapper::changeAlpha(double alpha) { changeAlpha(_materialInstance, alpha); } -void MaterialInstanceWrapper::setParameter(std::string name, double value) { +void MaterialInstanceWrapper::setFloatParameter(std::string name, double value) { std::unique_lock lock(_mutex); const Material* material = _materialInstance->getMaterial(); - if (!material->hasParameter(name.c_str())) { - throw std::runtime_error("MaterialInstanceWrapper::setParameter: Material does not have parameter \"" + name + "\"!"); + throw std::runtime_error("MaterialInstanceWrapper::setFloatParameter: Material does not have parameter \"" + name + "\"!"); } _materialInstance->setParameter(name.c_str(), (float)value); } -void MaterialInstanceWrapper::setBaseColorSRGB(std::vector rgba) { +void MaterialInstanceWrapper::setIntParameter(std::string name, int value) { + std::unique_lock lock(_mutex); + + const Material* material = _materialInstance->getMaterial(); + if (!material->hasParameter(name.c_str())) { + throw std::runtime_error("MaterialInstanceWrapper::setIntParameter: Material does not have parameter \"" + name + "\"!"); + } + + _materialInstance->setParameter(name.c_str(), value); +} + +void MaterialInstanceWrapper::setFloat3Parameter(std::string name, std::vector vector) { std::unique_lock lock(_mutex); + if (vector.size() != 3) { + throw std::runtime_error("MaterialInstanceWrapper::setFloat3Parameter: RGB vector must have 3 elements!"); + } + + const Material* material = _materialInstance->getMaterial(); + if (!material->hasParameter(name.c_str())) { + throw std::runtime_error("MaterialInstanceWrapper::setFloat3Parameter: Material does not have parameter \"" + name + "\"!"); + } - if (rgba.size() != 4) { - throw std::runtime_error("MaterialInstanceWrapper::setDefaultFloat4Parameter: RGBA vector must have 4 elements!"); + float x = vector[0]; + float y = vector[1]; + float z = vector[2]; + + _materialInstance->setParameter(name.c_str(), math::float3({x, y, z})); +} + +void MaterialInstanceWrapper::setFloat4Parameter(std::string name, std::vector vector) { + std::unique_lock lock(_mutex); + if (vector.size() != 4) { + throw std::runtime_error("MaterialInstanceWrapper::setFloat4Parameter: RGBA vector must have 4 elements!"); + } + + const Material* material = _materialInstance->getMaterial(); + if (!material->hasParameter(name.c_str())) { + throw std::runtime_error("MaterialInstanceWrapper::setFloat4Parameter: Material does not have parameter \"" + name + "\"!"); + } + + double r = vector[0]; + double g = vector[1]; + double b = vector[2]; + double a = vector[3]; + + _materialInstance->setParameter(name.c_str(), math::float4({r, g, b, a})); +} + +void MaterialInstanceWrapper::setMat3fParameter(std::string name, std::vector value) { + std::unique_lock lock(_mutex); + + const Material* material = _materialInstance->getMaterial(); + if (!material->hasParameter(name.c_str())) { + throw std::runtime_error("MaterialInstanceWrapper::setMat3fParameter: Material does not have parameter \"" + name + "\"!"); } - double r = rgba[0]; - double g = rgba[1]; - double b = rgba[2]; - double a = rgba[3]; + if (value.size() != 9) { + throw std::runtime_error("MaterialInstanceWrapper::setMat3fParameter: Value vector must have 9 elements!"); + } - _materialInstance->setParameter("baseColorFactor", math::float4({r, g, b, a})); + math::mat3f matrix = math::mat3f((float)value[0], (float)value[1], (float)value[2], (float)value[3], (float)value[4], (float)value[5], + (float)value[6], (float)value[7], (float)value[8]); + _materialInstance->setParameter(name.c_str(), matrix); } std::string MaterialInstanceWrapper::getName() { @@ -83,4 +141,54 @@ std::string MaterialInstanceWrapper::getName() { return _materialInstance->getName(); } +double MaterialInstanceWrapper::getFloatParameter(std::string name) { + const Material* material = _materialInstance->getMaterial(); + if (!material->hasParameter(name.c_str())) { + throw std::runtime_error("MaterialInstanceWrapper::getFloatParameter: Material does not have parameter \"" + name + "\"!"); + } + + return _materialInstance->getParameter(name.c_str()); +} + +int MaterialInstanceWrapper::getIntParameter(std::string name) { + const Material* material = _materialInstance->getMaterial(); + if (!material->hasParameter(name.c_str())) { + throw std::runtime_error("MaterialInstanceWrapper::getIntParameter: Material does not have parameter \"" + name + "\"!"); + } + + return _materialInstance->getParameter(name.c_str()); +} + +std::vector MaterialInstanceWrapper::getFloat3Parameter(std::string name) { + const Material* material = _materialInstance->getMaterial(); + if (!material->hasParameter(name.c_str())) { + throw std::runtime_error("MaterialInstanceWrapper::getFloat3Parameter: Material does not have parameter \"" + name + "\"!"); + } + + math::float3 vector = _materialInstance->getParameter(name.c_str()); + return {vector.x, vector.y, vector.z}; +} + +std::vector MaterialInstanceWrapper::getFloat4Parameter(std::string name) { + const Material* material = _materialInstance->getMaterial(); + if (!material->hasParameter(name.c_str())) { + throw std::runtime_error("MaterialInstanceWrapper::getFloat4Parameter: Material does not have parameter \"" + name + "\"!"); + } + + math::float4 vector = _materialInstance->getParameter(name.c_str()); + return {vector.r, vector.g, vector.b, vector.a}; +} + +std::vector MaterialInstanceWrapper::getMat3fParameter(std::string name) { + const Material* material = _materialInstance->getMaterial(); + if (!material->hasParameter(name.c_str())) { + throw std::runtime_error("MaterialInstanceWrapper::getMat3fParameter: Material does not have parameter \"" + name + "\"!"); + } + + math::mat3f matrix = _materialInstance->getParameter(name.c_str()); + const float* matrixArray = matrix.asArray(); + return {matrixArray[0], matrixArray[1], matrixArray[2], matrixArray[3], matrixArray[4], + matrixArray[5], matrixArray[6], matrixArray[7], matrixArray[8]}; +} + } // namespace margelo diff --git a/package/cpp/core/RNFMaterialInstanceWrapper.h b/package/cpp/core/RNFMaterialInstanceWrapper.h index 4962d2bf..7e18c0aa 100644 --- a/package/cpp/core/RNFMaterialInstanceWrapper.h +++ b/package/cpp/core/RNFMaterialInstanceWrapper.h @@ -28,8 +28,16 @@ class MaterialInstanceWrapper : public HybridObject { void setTransparencyMode(std::string mode); // Convenience method for updating baseColorFactor parameter void changeAlpha(double alpha); - void setParameter(std::string name, double value); - void setBaseColorSRGB(std::vector rgba); + void setFloatParameter(std::string name, double value); + void setIntParameter(std::string name, int value); + void setFloat3Parameter(std::string name, std::vector vector); + void setFloat4Parameter(std::string name, std::vector vector); + void setMat3fParameter(std::string name, std::vector value); + double getFloatParameter(std::string name); + int getIntParameter(std::string name); + std::vector getFloat3Parameter(std::string name); + std::vector getFloat4Parameter(std::string name); + std::vector getMat3fParameter(std::string name); std::string getName(); public: // Internal API diff --git a/package/cpp/core/RNFMaterialWrapper.cpp b/package/cpp/core/RNFMaterialWrapper.cpp index e63ec894..d97da1d4 100644 --- a/package/cpp/core/RNFMaterialWrapper.cpp +++ b/package/cpp/core/RNFMaterialWrapper.cpp @@ -10,13 +10,13 @@ namespace margelo { void MaterialWrapper::loadHybridMethods() { registerHybridMethod("createInstance", &MaterialWrapper::createInstance, this); - registerHybridMethod("setDefaultFloatParameter", &MaterialWrapper::setDefaultFloatParameter, this); + registerHybridMethod("setFloatParameter", &MaterialWrapper::setDefaultFloatParameter, this); registerHybridMethod("setDefaultTextureParameter", &MaterialWrapper::setDefaultTextureParameter, this); registerHybridMethod("getDefaultInstance", &MaterialWrapper::getDefaultInstance, this); - registerHybridMethod("setDefaultMat3fParameter", &MaterialWrapper::setDefaultMat3fParameter, this); - registerHybridMethod("setDefaultFloat3Parameter", &MaterialWrapper::setDefaultFloat3Parameter, this); - registerHybridMethod("setDefaultFloat4Parameter", &MaterialWrapper::setDefaultFloat4Parameter, this); - registerHybridMethod("setDefaultIntParameter", &MaterialWrapper::setDefaultIntParameter, this); + registerHybridMethod("setMat3fParameter", &MaterialWrapper::setDefaultMat3fParameter, this); + registerHybridMethod("setFloat3Parameter", &MaterialWrapper::setDefaultFloat3Parameter, this); + registerHybridMethod("setFloat4Parameter", &MaterialWrapper::setDefaultFloat4Parameter, this); + registerHybridMethod("setIntParameter", &MaterialWrapper::setDefaultIntParameter, this); } std::shared_ptr MaterialWrapper::createInstance() { return pointee()->createInstance(); diff --git a/package/src/types/MaterialInstance.ts b/package/src/types/MaterialInstance.ts index 45821464..513c532a 100644 --- a/package/src/types/MaterialInstance.ts +++ b/package/src/types/MaterialInstance.ts @@ -1,4 +1,4 @@ -import { RGBA } from './Color' +import { Float3, Float4, Mat3f } from './Math' export type CullingMode = 'none' | 'back' | 'front' | 'frontAndBack' @@ -8,11 +8,15 @@ export interface MaterialInstance { setCullingMode(mode: CullingMode): void setTransparencyMode(mode: TransparencyMode): void changeAlpha(alpha: number): void - setParameter(name: string, value: number): void - /** - * Changes the base color of the material. - * Assumes linear (0-1) linear sRGB color space. - */ - setBaseColorSRGB(color: RGBA): void + setFloatParameter(name: string, value: number): void + setIntParameter(name: string, value: number): void + setMat3fParameter(name: string, value: Mat3f): void + setFloat3Parameter(name: string, vector: Float3): void + setFloat4Parameter(name: string, vector: Float4): void + getFloatParameter(name: string): number + getIntParameter(name: string): number + getMat3fParameter(name: string): Mat3f + getFloat3Parameter(name: string): Float3 + getFloat4Parameter(name: string): Float4 readonly name: string }