diff --git a/src/lua_component.cpp b/src/lua_component.cpp index 8e48081..d03cfdc 100644 --- a/src/lua_component.cpp +++ b/src/lua_component.cpp @@ -63,7 +63,7 @@ namespace lua_component void setColor(CRGBA color) { - VehicleRenderer::get()->setMaterialColor(_vehicle, _material, _geometry, {color.r, color.g, color.b, color.a}); + VehicleRenderer::get()->setMaterialColor(_vehicle, _material, _geometry, {color.red, color.green, color.blue, color.alpha}); } CRGBA getColor() const @@ -94,6 +94,87 @@ namespace lua_component VehicleRenderer::get()->resetMaterialTexture(_vehicle, _material); } + + void VehicleMaterial::setAmbient(RwReal ambient) + { + VehicleRenderer::get()->setMaterialAmbient(_vehicle, _material, ambient); + } + + RwReal VehicleMaterial::getAmbient() const + { + const auto* matProps = VehicleRenderer::get()->getMaterialProperties(_vehicle, _material); + if (matProps && matProps->_reAmbient) + return matProps->_ambient; + else + return _material->surfaceProps.ambient; + } + + void VehicleMaterial::resetAmbient() + { + VehicleRenderer::get()->resetMaterialAmbient(_vehicle, _material); + } + + void VehicleMaterial::setDiffuse(RwReal diffuse) + { + VehicleRenderer::get()->setMaterialDiffuse(_vehicle, _material, diffuse); + } + + RwReal VehicleMaterial::getDiffuse() const + { + const auto* matProps = VehicleRenderer::get()->getMaterialProperties(_vehicle, _material); + if (matProps && matProps->_reDiffuse) + return matProps->_diffuse; + else + return _material->surfaceProps.diffuse; + } + + void VehicleMaterial::resetDiffuse() + { + VehicleRenderer::get()->resetMaterialDiffuse(_vehicle, _material); + } + + void VehicleMaterial::setSpecular(RwReal specular) + { + VehicleRenderer::get()->setMaterialSpecular(_vehicle, _material, specular); + } + + RwReal VehicleMaterial::getSpecular() const + { + const auto* matProps = VehicleRenderer::get()->getMaterialProperties(_vehicle, _material); + if (matProps && matProps->_reSpecular) + return matProps->_specular; + else + return _material->surfaceProps.specular; + } + + void VehicleMaterial::resetSpecular() + { + VehicleRenderer::get()->resetMaterialSpecular(_vehicle, _material); + } + + sol::table VehicleMaterial::getSurfaceProperties(sol::this_state ts) const + { + sol::table props = sol::state_view{ ts }.create_table(); + const auto* matProps = VehicleRenderer::get()->getMaterialProperties(_vehicle, _material); + props["ambient"] = matProps && matProps->_reAmbient ? matProps->_ambient : _material->surfaceProps.ambient; + props["diffuse"] = matProps && matProps->_reDiffuse ? matProps->_diffuse : _material->surfaceProps.diffuse; + props["specular"] = matProps && matProps->_reSpecular ? matProps->_specular : _material->surfaceProps.specular; + return props; + } + + void VehicleMaterial::setSurfaceProperties(sol::table props) + { + RwReal ambient = props.get_or("ambient", _material->surfaceProps.ambient); + RwReal diffuse = props.get_or("diffuse", _material->surfaceProps.diffuse); + RwReal specular = props.get_or("specular", _material->surfaceProps.specular); + VehicleRenderer::get()->setMaterialSurfaceProperties(_vehicle, _material, ambient, diffuse, specular); + } + + void VehicleMaterial::resetSurfaceProperties() + { + VehicleRenderer::get()->resetMaterialSurfaceProperties(_vehicle, _material); + } + uintptr_t getRawPointer() const { return reinterpret_cast(_material); @@ -132,7 +213,7 @@ namespace lua_component return (RpAtomicGetVisibilityPlugin(_atomic)->m_wFlags & flag) != 0; } - void setAtomicFlag(unsigned short flag, bool value) + void setAtomicFlag(unsigned int flag, bool value) { if (value) CVisibilityPlugins::SetAtomicFlag(_atomic, flag); @@ -336,7 +417,20 @@ namespace lua_component "reset_color", &VehicleMaterial::resetColor, "set_texture", &VehicleMaterial::setTexture, "get_texture", &VehicleMaterial::getTexture, - "reset_texture", &VehicleMaterial::resetTexture); + "reset_texture", &VehicleMaterial::resetTexture, + "set_ambient", &VehicleMaterial::setAmbient, + "get_ambient", &VehicleMaterial::getAmbient, + "reset_ambient", &VehicleMaterial::resetAmbient, + "set_diffuse", &VehicleMaterial::setDiffuse, + "get_diffuse", &VehicleMaterial::getDiffuse, + "reset_diffuse", &VehicleMaterial::resetDiffuse, + "set_specular", &VehicleMaterial::setSpecular, + "get_specular", &VehicleMaterial::getSpecular, + "reset_specular", &VehicleMaterial::resetSpecular, + "get_properties", & VehicleMaterial::getSurfaceProperties, + "set_properties", & VehicleMaterial::setSurfaceProperties, + "reset_properties", & VehicleMaterial::resetSurfaceProperties); + module.new_enum("component_state", "DISABLED", VISIBILITY_DISABLED, "ENABLED", VISIBILITY_ENABLED, diff --git a/src/vehicle_renderer.cpp b/src/vehicle_renderer.cpp index e5b328d..b9c905b 100644 --- a/src/vehicle_renderer.cpp +++ b/src/vehicle_renderer.cpp @@ -73,6 +73,107 @@ void VehicleRenderer::resetMaterialTexture(CVehicle* veh, RpMaterial* material) } } +void VehicleRenderer::setMaterialAmbient(CVehicle* veh, RpMaterial* material, RwReal ambient) +{ + auto& matProps = getVehicleMaterialProperties(veh)[material]; + matProps._reAmbient = true; + matProps._ambient = ambient; +} + +void VehicleRenderer::setMaterialDiffuse(CVehicle* veh, RpMaterial* material, RwReal diffuse) +{ + auto& matProps = getVehicleMaterialProperties(veh)[material]; + matProps._reDiffuse = true; + matProps._diffuse = diffuse; +} + +void VehicleRenderer::setMaterialSpecular(CVehicle* veh, RpMaterial* material, RwReal specular) +{ + auto& matProps = getVehicleMaterialProperties(veh)[material]; + matProps._reSpecular = true; + matProps._specular = specular; +} + +void VehicleRenderer::resetMaterialAmbient(CVehicle* veh, RpMaterial* material) +{ + if (isInitialized() && _vehicleData->exists(veh)) + { + auto& props = _vehicleData->get(veh)._materialProperties; + auto it = props.find(material); + if (it != props.end()) + { + it->second._reAmbient = false; + } + } +} + +void VehicleRenderer::resetMaterialDiffuse(CVehicle* veh, RpMaterial* material) +{ + if (isInitialized() && _vehicleData->exists(veh)) + { + auto& props = _vehicleData->get(veh)._materialProperties; + auto it = props.find(material); + if (it != props.end()) + { + it->second._reDiffuse = false; + } + } +} + +void VehicleRenderer::resetMaterialSpecular(CVehicle* veh, RpMaterial* material) +{ + if (isInitialized() && _vehicleData->exists(veh)) + { + auto& props = _vehicleData->get(veh)._materialProperties; + auto it = props.find(material); + if (it != props.end()) + { + it->second._reSpecular = false; + } + } +} + +void VehicleRenderer::setMaterialSurfaceProperties(CVehicle* veh, RpMaterial* material, RwReal ambient, RwReal diffuse, RwReal specular) +{ + auto& matProps = getVehicleMaterialProperties(veh)[material]; + matProps._reAmbient = true; + matProps._ambient = ambient; + matProps._reDiffuse = true; + matProps._diffuse = diffuse; + matProps._reSpecular = true; + matProps._specular = specular; +} + +void VehicleRenderer::resetMaterialSurfaceProperties(CVehicle* veh, RpMaterial* material) +{ + if (isInitialized() && _vehicleData->exists(veh)) + { + auto& props = _vehicleData->get(veh)._materialProperties; + auto it = props.find(material); + if (it != props.end()) + { + it->second._reAmbient = false; + it->second._reDiffuse = false; + it->second._reSpecular = false; + } + } +} + + +const VehicleRenderer::MaterialProperties* VehicleRenderer::getMaterialProperties(CVehicle* veh, RpMaterial* material) const +{ + if (_vehicleData && _vehicleData->exists(veh)) + { + auto& props = _vehicleData->get(veh)._materialProperties; + auto it = props.find(material); + if (it != props.end()) + return &it->second; + } + return nullptr; +} + + + void VehicleRenderer::processRender(CVehicle* veh) { if (isInitialized() && _vehicleData->exists(veh)) @@ -99,6 +200,22 @@ void VehicleRenderer::processRender(CVehicle* veh) it.second._retexture = false; } } + + if (it.second._reAmbient) + { + it.second._originalAmbient = it.first->surfaceProps.ambient; + it.first->surfaceProps.ambient = it.second._ambient; + } + if (it.second._reDiffuse) + { + it.second._originalDiffuse = it.first->surfaceProps.diffuse; + it.first->surfaceProps.diffuse = it.second._diffuse; + } + if (it.second._reSpecular) + { + it.second._originalSpecular = it.first->surfaceProps.specular; + it.first->surfaceProps.specular = it.second._specular; + } } } } @@ -118,6 +235,18 @@ void VehicleRenderer::postRender(CVehicle* veh) { it.first->texture = it.second._originalTexture; } + if (it.second._reAmbient) + { + it.first->surfaceProps.ambient = it.second._originalAmbient; + } + if (it.second._reDiffuse) + { + it.first->surfaceProps.diffuse = it.second._originalDiffuse; + } + if (it.second._reSpecular) + { + it.first->surfaceProps.specular = it.second._originalSpecular; + } } } } diff --git a/src/vehicle_renderer.h b/src/vehicle_renderer.h index 428e6e7..161ba9f 100644 --- a/src/vehicle_renderer.h +++ b/src/vehicle_renderer.h @@ -23,6 +23,7 @@ #pragma once #include "singleton.h" +#include "extender/VehicleExtender_SA.h" #include "forward_declarations.h" #include "pool_object_extender.h" @@ -32,11 +33,20 @@ class VehicleRenderer : public Singleton struct MaterialProperties { MaterialProperties() : - _color{0, 0, 0, 0}, + _color{ 0, 0, 0, 0 }, + _ambient(0.5f), + _diffuse(1.0f), + _specular(1.0f), _recolor(false), _retexture(false), - _originalColor{0, 0, 0, 0}, + _reAmbient(false), + _reDiffuse(false), + _reSpecular(false), + _originalColor{ 0, 0, 0, 0 }, _originalTexture(nullptr), + _originalAmbient(0.5f), + _originalDiffuse(1.0f), + _originalSpecular(1.0f), _originalGeometryFlags(0), _geometry(nullptr) { @@ -50,6 +60,15 @@ class VehicleRenderer : public Singleton RwRGBA _originalColor; RwTexture* _originalTexture; RwInt32 _originalGeometryFlags; + RwReal _ambient; + bool _reAmbient; + RwReal _diffuse; + bool _reDiffuse; + RwReal _specular; + bool _reSpecular; + RwReal _originalAmbient; + RwReal _originalDiffuse; + RwReal _originalSpecular; }; struct VehicleData @@ -66,6 +85,15 @@ class VehicleRenderer : public Singleton void setMaterialTexture(CVehicle* veh, RpMaterial* material, std::shared_ptr texture); void resetMaterialColor(CVehicle* veh, RpMaterial* material); void resetMaterialTexture(CVehicle* veh, RpMaterial* material); + void setMaterialAmbient(CVehicle* veh, RpMaterial* material, RwReal ambient); + void setMaterialDiffuse(CVehicle* veh, RpMaterial* material, RwReal diffuse); + void setMaterialSpecular(CVehicle* veh, RpMaterial* material, RwReal specular); + void resetMaterialAmbient(CVehicle* veh, RpMaterial* material); + void resetMaterialDiffuse(CVehicle* veh, RpMaterial* material); + void resetMaterialSpecular(CVehicle* veh, RpMaterial* material); + const MaterialProperties* getMaterialProperties(CVehicle* veh, RpMaterial* material) const; + void setMaterialSurfaceProperties(CVehicle* veh, RpMaterial* material, RwReal ambient, RwReal diffuse, RwReal specular); + void resetMaterialSurfaceProperties(CVehicle* veh, RpMaterial* material); void processRender(CVehicle* veh); void postRender(CVehicle* veh); bool isInitialized() const { return _vehicleData != nullptr; }