Skip to content

Commit

Permalink
fix: MaterialInstance API (#204)
Browse files Browse the repository at this point in the history
There were some differences between the TS types and the native methods.
This PR also aligned MaterialInstance implementation with the Material
implementation.
  • Loading branch information
hannojg authored Jun 17, 2024
1 parent c7c79ff commit bd8a6ac
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 35 deletions.
16 changes: 8 additions & 8 deletions package/cpp/core/RNFMaterialImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -59,11 +59,11 @@ void MaterialImpl::setDefaultTextureParameter(std::string name, Texture* texture
void MaterialImpl::setDefaultFloat3Parameter(std::string name, std::vector<double> 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];
Expand All @@ -76,11 +76,11 @@ void MaterialImpl::setDefaultFloat3Parameter(std::string name, std::vector<doubl
void MaterialImpl::setDefaultFloat4Parameter(std::string name, std::vector<double> 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];
Expand All @@ -99,11 +99,11 @@ void MaterialImpl::setDefaultMat3fParameter(std::string name, std::vector<double
std::unique_lock lock(_mutex);

if (!_material->hasParameter(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],
Expand Down
134 changes: 121 additions & 13 deletions package/cpp/core/RNFMaterialInstanceWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,23 @@
#include "RNFCullingModeEnum.h"
#include "RNFTransparencyModeEnum.h"
#include <filament/Material.h>
#include <math/mat3.h>

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);
}

Expand Down Expand Up @@ -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<double> 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<double> 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<double> 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<double> 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() {
Expand All @@ -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<float>(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<int>(name.c_str());
}

std::vector<double> 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<math::float3>(name.c_str());
return {vector.x, vector.y, vector.z};
}

std::vector<double> 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<math::float4>(name.c_str());
return {vector.r, vector.g, vector.b, vector.a};
}

std::vector<double> 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<math::mat3f>(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
12 changes: 10 additions & 2 deletions package/cpp/core/RNFMaterialInstanceWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<double> rgba);
void setFloatParameter(std::string name, double value);
void setIntParameter(std::string name, int value);
void setFloat3Parameter(std::string name, std::vector<double> vector);
void setFloat4Parameter(std::string name, std::vector<double> vector);
void setMat3fParameter(std::string name, std::vector<double> value);
double getFloatParameter(std::string name);
int getIntParameter(std::string name);
std::vector<double> getFloat3Parameter(std::string name);
std::vector<double> getFloat4Parameter(std::string name);
std::vector<double> getMat3fParameter(std::string name);
std::string getName();

public: // Internal API
Expand Down
10 changes: 5 additions & 5 deletions package/cpp/core/RNFMaterialWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<MaterialInstanceWrapper> MaterialWrapper::createInstance() {
return pointee()->createInstance();
Expand Down
18 changes: 11 additions & 7 deletions package/src/types/MaterialInstance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RGBA } from './Color'
import { Float3, Float4, Mat3f } from './Math'

export type CullingMode = 'none' | 'back' | 'front' | 'frontAndBack'

Expand All @@ -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
}

0 comments on commit bd8a6ac

Please sign in to comment.