Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/pages/attributesJSON.rst
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,6 @@ The Light Setup attributes JSON should contain a single cell named "lights" that
"type"
- string
- The type of the light. "point" and "directional" are currently supported.
"position_model"
- string
- They frame to use to place the light. "global", meaning stage's origin, and "camera", meaning place relative to a (potentially moving) camera, are currently supported.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, the "object" mode cannot be supported at the moment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this would require more configuration specifications at the scene instance level, to specify which object instance the light should "orbit"

@bigbike bigbike May 3, 2021

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not "orbit". Just stay fixed relative to the object.
In that case, the "light" should be in the scene graph, and be attached to a child node of that object.

@jturner65 jturner65 May 3, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed orbit :). (but yeah, I was kind of abusing terminology there, excuse me).

8 changes: 4 additions & 4 deletions examples/tutorials/lighting_tutorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def main(show_imgs=True, save_imgs=False):

# create and register new light setup:
my_scene_lighting_setup = [
LightInfo(vector=[0.0, 2.0, 0.6, 0.0], model=LightPositionModel.GLOBAL)
LightInfo(vector=[0.0, 2.0, 0.6, 0.0], model=LightPositionModel.Global)
]
sim.set_light_setup(my_scene_lighting_setup, "my_scene_lighting")

Expand Down Expand Up @@ -142,7 +142,7 @@ def main(show_imgs=True, save_imgs=False):

# create a custom light setup
my_default_lighting = [
LightInfo(vector=[2.0, 2.0, 1.0, 0.0], model=LightPositionModel.CAMERA)
LightInfo(vector=[2.0, 2.0, 1.0, 0.0], model=LightPositionModel.Camera)
]
# overwrite the default DEFAULT_LIGHTING_KEY light setup
sim.set_light_setup(my_default_lighting)
Expand All @@ -165,7 +165,7 @@ def main(show_imgs=True, save_imgs=False):
LightInfo(
vector=[2.0, 1.5, 5.0, 1.0],
color=[0.0, 100.0, 100.0],
model=LightPositionModel.GLOBAL,
model=LightPositionModel.Global,
)
]
sim.set_light_setup(light_setup_2, "my_custom_lighting")
Expand Down Expand Up @@ -196,7 +196,7 @@ def main(show_imgs=True, save_imgs=False):
LightInfo(
vector=[0.0, 0.0, 1.0, 0.0],
color=[1.6, 1.6, 1.4],
model=LightPositionModel.CAMERA,
model=LightPositionModel.Camera,
)
]

Expand Down
8 changes: 4 additions & 4 deletions src/esp/bindings/GfxBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ void initGfxBindings(py::module& m) {
py::enum_<LightPositionModel>(
m, "LightPositionModel",
R"(Defines the coordinate frame of a light source.)")
.value("CAMERA", LightPositionModel::CAMERA)
.value("GLOBAL", LightPositionModel::GLOBAL)
.value("OBJECT", LightPositionModel::OBJECT);
.value("Camera", LightPositionModel::Camera)
.value("Global", LightPositionModel::Global)
.value("Object", LightPositionModel::Object);

py::enum_<LightType>(
m, "LightType", R"(Defines the type of light described by the LightInfo)")
Expand All @@ -178,7 +178,7 @@ void initGfxBindings(py::module& m) {
.def(py::init())
.def(py::init<Magnum::Vector4, Magnum::Color3, LightPositionModel>(),
"vector"_a, "color"_a = Magnum::Color3{1},
"model"_a = LightPositionModel::GLOBAL)
"model"_a = LightPositionModel::Global)
.def_readwrite("vector", &LightInfo::vector)
.def_readwrite("color", &LightInfo::color)
.def_readwrite("model", &LightInfo::model)
Expand Down
6 changes: 3 additions & 3 deletions src/esp/gfx/LightSetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ Magnum::Vector4 getLightPositionRelativeToCamera(
"w == 1 for a point light");

switch (light.model) {
case LightPositionModel::OBJECT:
case LightPositionModel::Object:
Comment thread
Skylion007 marked this conversation as resolved.
return transformationMatrix * light.vector;
case LightPositionModel::GLOBAL:
case LightPositionModel::Global:
return cameraMatrix * light.vector;
case LightPositionModel::CAMERA:
case LightPositionModel::Camera:
return light.vector;
}

Expand Down
8 changes: 4 additions & 4 deletions src/esp/gfx/LightSetup.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ namespace gfx {

enum class LightPositionModel {
/** @brief Light position is relative to the camera */
CAMERA = 0,
Camera = 0,
/** @brief Light position is relative to scene */
GLOBAL = 1,
Global = 1,
/** @brief Light position is relative to the object being rendered */
OBJECT = 2,
Object = 2,
};

enum class LightType {
Expand All @@ -40,7 +40,7 @@ struct LightInfo {
// directional light with no distance attenuation.
Magnum::Vector4 vector;
Magnum::Color3 color{1};
LightPositionModel model = LightPositionModel::GLOBAL;
LightPositionModel model = LightPositionModel::Global;
};

bool operator==(const LightInfo& a, const LightInfo& b);
Expand Down
9 changes: 8 additions & 1 deletion src/esp/metadata/attributes/LightLayoutAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ const std::map<std::string, esp::gfx::LightType>
LightInstanceAttributes::LightTypeNamesMap = {
{"point", esp::gfx::LightType::Point},
{"directional", esp::gfx::LightType::Directional},
};
{"spot", esp::gfx::LightType::Spot}};

const std::map<std::string, esp::gfx::LightPositionModel>
LightInstanceAttributes::LightPositionNamesMap = {
{"global", esp::gfx::LightPositionModel::Global},
{"camera", esp::gfx::LightPositionModel::Camera},
{"object", esp::gfx::LightPositionModel::Object}};

LightInstanceAttributes::LightInstanceAttributes(const std::string& handle)
: AbstractAttributes("LightInstanceAttributes", handle) {
Expand All @@ -22,6 +28,7 @@ LightInstanceAttributes::LightInstanceAttributes(const std::string& handle)
setColor({1.0, 1.0, 1.0});
setIntensity(1.0);
setType(static_cast<int>(esp::gfx::LightType::Point));
setPositionModel(static_cast<int>(esp::gfx::LightPositionModel::Global));
// ignored for all but spot lights
setInnerConeAngle(0.0_radf);
setOuterConeAngle(90.0_degf);
Expand Down
22 changes: 21 additions & 1 deletion src/esp/metadata/attributes/LightLayoutAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,19 @@ class LightInstanceAttributes : public AbstractAttributes {
/**
* @brief Constant static map to provide mappings from string tags to @ref
* esp::gfx::LightType values. This will be used to map values set in json
* for light type to @ref esp::gfx::LightType. Keys must be lowercase.
* for light type to @ref esp::gfx::LightType. Keys must be lowercase - will
* support any case values in JSON.
*/
static const std::map<std::string, esp::gfx::LightType> LightTypeNamesMap;

/**
* @brief Constant static map to provide mappings from string tags to @ref
* esp::gfx::LightPositionModel values. This will be used to map values set
* in json to specify what translations are measured from for a lighting
* instance.
*/
static const std::map<std::string, esp::gfx::LightPositionModel>
LightPositionNamesMap;
explicit LightInstanceAttributes(const std::string& handle = "");

/**
Expand Down Expand Up @@ -61,6 +71,16 @@ class LightInstanceAttributes : public AbstractAttributes {
void setType(int type) { setInt("type", type); }
int getType() const { return getInt("type"); }

/**
* @brief Get/Set the position model to use when placing the light - whether
* the lights translation should be relative to the camera, the global scene
* origin, or some object.
*/
void setPositionModel(int position_model) {
setInt("position_model", position_model);
}
int getPositionModel() const { return getInt("position_model"); }

/**
* @brief Get/Set inner cone angle for spotlights. Should be ignored for
* other lights
Expand Down
62 changes: 51 additions & 11 deletions src/esp/metadata/managers/LightLayoutAttributesManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,49 @@ void LightLayoutAttributesManager::setLightInstanceValsFromJSONDoc(
lightAttribs->setIntensity(intensity);
});

// set frame of reference for light transformation
int posMdleVal = -1;
std::string tmpPosMdleVal = "";
if (io::readMember<std::string>(jsonConfig, "position_model",
tmpPosMdleVal)) {
std::string strToLookFor = Cr::Utility::String::lowercase(tmpPosMdleVal);
if (LightInstanceAttributes::LightPositionNamesMap.count(strToLookFor)) {
posMdleVal = static_cast<int>(
LightInstanceAttributes::LightPositionNamesMap.at(strToLookFor));
} else {
LOG(WARNING)
<< "LightLayoutAttributesManager::setLightInstanceValsFromJSONDoc : "
"Position Model Value in JSON : `"
<< posMdleVal
<< "` does not map to a valid "
"LightInstanceAttributes::LightPositionNamesMap value, so "
"defaulting LightInfo position model to "
"esp::gfx::LightPositionModel::Global.";
posMdleVal = static_cast<int>(esp::gfx::LightPositionModel::Global);
}
lightAttribs->setPositionModel(posMdleVal);
}

// type of light - should map to enum values in esp::gfx::LightType
int typeVal = -1;
std::string tmpVal = "";
if (io::readMember<std::string>(jsonConfig, "type", tmpVal)) {
std::string strToLookFor = Cr::Utility::String::lowercase(tmpVal);
if (LightInstanceAttributes::LightTypeNamesMap.count(strToLookFor)) {
std::string tmpTypeVal = "";
if (io::readMember<std::string>(jsonConfig, "type", tmpTypeVal)) {
std::string strToLookFor = Cr::Utility::String::lowercase(tmpTypeVal);
if (strToLookFor.compare("spot") == 0) {
// TODO remove this if block to support spot lights
LOG(WARNING)
<< "LightLayoutAttributesManager::setLightInstanceValsFromJSONDoc : "
"Type spotlight specified in JSON not currently supported, so "
"defaulting LightInfo type to esp::gfx::LightType::Point.";
typeVal = static_cast<int>(esp::gfx::LightType::Point);
} else if (LightInstanceAttributes::LightTypeNamesMap.count(strToLookFor)) {
typeVal = static_cast<int>(
LightInstanceAttributes::LightTypeNamesMap.at(strToLookFor));
} else {
LOG(WARNING)
<< "LightLayoutAttributesManager::setLightInstanceValsFromJSONDoc : "
"Type Value in json : `"
<< tmpVal
"Type Value in JSON : `"
<< tmpTypeVal
<< "` does not map to a valid "
"LightInstanceAttributes::LightTypeNamesMap value, so "
"defaulting LightInfo type to esp::gfx::LightType::Point.";
Expand All @@ -150,10 +180,13 @@ void LightLayoutAttributesManager::setLightInstanceValsFromJSONDoc(
// read spotlight params
if (jsonConfig.HasMember("spot")) {
if (!jsonConfig["spot"].IsObject()) {
// TODO prune NOTE: component when spotlights are supported
LOG(WARNING)
<< "LightLayoutAttributesManager::setValsFromJSONDoc : \"spot\" "
"cell in JSON config unable to be parsed to set "
"spotlight parameters so skipping.";
"spotlight parameters so skipping. NOTE : Spotlights not "
"currently supported, so cone anble values are ignored and light "
"will be created as a point light.";
} else {
const auto& spotArea = jsonConfig["spot"];
// set inner cone angle
Expand All @@ -170,7 +203,7 @@ void LightLayoutAttributesManager::setLightInstanceValsFromJSONDoc(
lightAttribs->setOuterConeAngle(outerConeAngle);
});
}
} // if member spot present
} // if JSON object 'spot' present
} // LightLayoutAttributesManager::setValsFromJSONDoc

LightLayoutAttributes::ptr LightLayoutAttributesManager::initNewObjectInternal(
Expand Down Expand Up @@ -208,8 +241,12 @@ gfx::LightSetup LightLayoutAttributesManager::createLightSetupFromAttributes(
if (numLightInstances == 0) {
// setup default LightInfo instances - lifted from LightSetup.cpp.
// TODO create default attributes describing these lights?
return gfx::LightSetup{{{1.0, 1.0, 0.0, 0.0}, {0.75, 0.75, 0.75}},
{{-0.5, 0.0, 1.0, 0.0}, {0.4, 0.4, 0.4}}};
return gfx::LightSetup{{.vector = {1.0, 1.0, 0.0, 0.0},
.color = {0.75, 0.75, 0.75},
.model = gfx::LightPositionModel::Global},
{.vector = {-0.5, 0.0, 1.0, 0.0},
.color = {0.4, 0.4, 0.4},
.model = gfx::LightPositionModel::Global}};
} else {
const std::map<std::string, LightInstanceAttributes::ptr>&
lightInstances = lightLayoutAttributes->getLightInstances();
Expand All @@ -218,6 +255,8 @@ gfx::LightSetup LightLayoutAttributesManager::createLightSetupFromAttributes(
const LightInstanceAttributes::ptr& lightAttr = elem.second;
const int type = lightAttr->getType();
const gfx::LightType typeEnum = static_cast<gfx::LightType>(type);
const gfx::LightPositionModel posModelEnum =
static_cast<gfx::LightPositionModel>(lightAttr->getPositionModel());
const Magnum::Color3 color =
lightAttr->getColor() * lightAttr->getIntensity();
Magnum::Vector4 lightVector;
Expand All @@ -240,7 +279,8 @@ gfx::LightSetup LightLayoutAttributesManager::createLightSetupFromAttributes(
lightVector = {lightAttr->getPosition(), 1.0f};
}
} // switch on type
res.push_back({lightVector, color});
res.push_back(
{.vector = lightVector, .color = color, .model = posModelEnum});
} // for each light instance described
} // if >0 light instances described
} // lightLayoutAttributes of requested name exists
Expand Down
3 changes: 3 additions & 0 deletions src/tests/AttributesManagersTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ TEST_F(AttributesManagersTest, AttributesManagers_LightJSONLoadTest) {
"intensity": -0.1,
"color": [2,1,-1],
"type": "directional",
"position_model" : "camera",
"spot": {
"innerConeAngle": -0.75,
"outerConeAngle": -1.57
Expand Down Expand Up @@ -486,6 +487,8 @@ TEST_F(AttributesManagersTest, AttributesManagers_LightJSONLoadTest) {
ASSERT_EQ(lightAttr->getIntensity(), -0.1);
ASSERT_EQ(lightAttr->getType(),
static_cast<int>(esp::gfx::LightType::Directional));
ASSERT_EQ(lightAttr->getPositionModel(),
static_cast<int>(esp::gfx::LightPositionModel::Camera));
ASSERT_EQ(lightAttr->getInnerConeAngle(), -0.75_radf);
ASSERT_EQ(lightAttr->getOuterConeAngle(), -1.57_radf);
} // AttributesManagers_LightJSONLoadTest
Expand Down
4 changes: 2 additions & 2 deletions src/tests/SimTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ struct SimTest : Cr::TestSuite::Tester {

LightSetup lightSetup1{{Magnum::Vector4{1.0f, 1.5f, 0.5f, 0.0f},
{5.0, 5.0, 0.0},
LightPositionModel::CAMERA}};
LightPositionModel::Camera}};
LightSetup lightSetup2{{Magnum::Vector4{0.0f, 0.5f, 1.0f, 0.0f},
{0.0, 5.0, 5.0},
LightPositionModel::CAMERA}};
LightPositionModel::Camera}};
};
struct {
// display name for sim being tested
Expand Down
2 changes: 1 addition & 1 deletion tests/test_light_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_set_default_light_setup(make_cfg_settings):
assert sim.get_light_setup() == light_setup

# ensure modifications to local light setup variable are not reflected in sim
light_setup[0].model = LightPositionModel.CAMERA
light_setup[0].model = LightPositionModel.Camera
assert sim.get_light_setup() != light_setup

sim.set_light_setup(light_setup, DEFAULT_LIGHTING_KEY)
Expand Down