mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-28 03:57:44 -06:00
Merge pull request #294 from pat-the-wizard/docs/261-environment-light
3D: layer.newLight lists the Environment light and how to set its source; parity notes reflections (#261)
This commit is contained in:
@@ -220,7 +220,9 @@ fn new_light(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let cid = comp_id(s, p)?;
|
||||
let comp = s.project.comp(cid).ok_or(EngineError::NoComp)?.clone();
|
||||
let kind = match p.get("kind").or_else(|| p.get("type")) {
|
||||
Some(_) => light_kind_p(p, "kind").or_else(|| light_kind_p(p, "type")).ok_or_else(|| bad("layer.newLight", "kind: Parallel|Spot|Point|Ambient"))?,
|
||||
Some(_) => {
|
||||
light_kind_p(p, "kind").or_else(|| light_kind_p(p, "type")).ok_or_else(|| bad("layer.newLight", "kind: Parallel|Spot|Point|Ambient|Environment"))?
|
||||
}
|
||||
None => LightKind::Spot,
|
||||
};
|
||||
let name = str_p(p, "name").unwrap_or("Light 1").to_string();
|
||||
@@ -239,9 +241,11 @@ fn light_settings(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let t = time_p(s, p, Some(&comp));
|
||||
let name = str_p(p, "name").map(str::to_string);
|
||||
let kind = match p.get("kind").or_else(|| p.get("type")) {
|
||||
Some(_) => {
|
||||
Some(light_kind_p(p, "kind").or_else(|| light_kind_p(p, "type")).ok_or_else(|| bad("layer.lightSettings", "kind: Parallel|Spot|Point|Ambient"))?)
|
||||
}
|
||||
Some(_) => Some(
|
||||
light_kind_p(p, "kind")
|
||||
.or_else(|| light_kind_p(p, "type"))
|
||||
.ok_or_else(|| bad("layer.lightSettings", "kind: Parallel|Spot|Point|Ambient|Environment"))?,
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
s.edit("Light Settings", None, |proj, _| {
|
||||
@@ -662,7 +666,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Light...",
|
||||
["Layer", "New"],
|
||||
Some("Cmd+Alt+Shift+L"),
|
||||
"{kind?: Parallel|Spot|Point|Ambient (default Spot), name?, color?, intensity?, coneAngle?, coneFeather?, falloff?: None|Smooth|Inverse Square Clamped, radius?, falloffDistance?, castsShadows?, shadowDarkness?, shadowDiffusion?, position? [x,y,z], poi? [x,y,z]}",
|
||||
"{kind?: Parallel|Spot|Point|Ambient|Environment (default Spot; Environment lights and reflects from an equirectangular image layer: prop.set its lightOptions/source to that layer's id, or leave it empty for the comp's Environment Layer, see layer.environment), name?, color?, intensity?, coneAngle?, coneFeather?, falloff?: None|Smooth|Inverse Square Clamped, radius?, falloffDistance?, castsShadows?, shadowDarkness?, shadowDiffusion?, position? [x,y,z], poi? [x,y,z]}",
|
||||
has_comp,
|
||||
new_light
|
||||
),
|
||||
@@ -689,7 +693,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Light Settings...",
|
||||
[],
|
||||
None,
|
||||
"{layer?, name?, kind?, color?, intensity?, coneAngle?, coneFeather?, falloff?, radius?, falloffDistance?, castsShadows?, shadowDarkness?, shadowDiffusion?, position?, poi?}",
|
||||
"{layer?, name?, kind?: Parallel|Spot|Point|Ambient|Environment, color?, intensity?, coneAngle?, coneFeather?, falloff?, radius?, falloffDistance?, castsShadows?, shadowDarkness?, shadowDiffusion?, position?, poi?}",
|
||||
has_comp,
|
||||
light_settings
|
||||
),
|
||||
|
||||
@@ -106,6 +106,31 @@ fn new_light_and_change_type() {
|
||||
assert!(s.execute("layer.newLight", json!({"kind": "Laser"})).is_err());
|
||||
}
|
||||
|
||||
/// The Environment light is listed in `layer.newLight`'s help and in the kind errors, and takes
|
||||
/// its equirectangular source as a layer id (#261).
|
||||
#[test]
|
||||
fn environment_light_is_listed_and_takes_a_source_layer() {
|
||||
let mut s = session();
|
||||
let spec = crate::command_specs().iter().find(|c| c.id == "layer.newLight").unwrap();
|
||||
assert!(spec.params.contains("lightOptions/source"), "{}", spec.params);
|
||||
let e = s.execute("layer.newLight", json!({"kind": "Laser"})).unwrap_err().to_string();
|
||||
let point = s.execute("layer.newLight", json!({"kind": "Point"})).unwrap()["layer"].as_u64().unwrap();
|
||||
let e2 = s.execute("layer.lightSettings", json!({"layer": point, "kind": "Laser"})).unwrap_err().to_string();
|
||||
for k in LightKind::ALL {
|
||||
assert!(spec.params.contains(k.label()), "help lists {}: {}", k.label(), spec.params);
|
||||
assert!(e.contains(k.label()) && e2.contains(k.label()), "{e} / {e2}");
|
||||
}
|
||||
let sky = s.execute("layer.newSolid", json!({"width": 256, "height": 128, "name": "Sky"})).unwrap()["layer"].as_u64().unwrap();
|
||||
let env = s.execute("layer.newLight", json!({"kind": "Environment", "name": "Env"})).unwrap()["layer"].as_u64().unwrap();
|
||||
let source = s.active_comp().unwrap().layer(effectcraft_project::LayerId(env)).unwrap().source.clone();
|
||||
assert_eq!(source, LayerSource::Light { kind: LightKind::Environment });
|
||||
assert_eq!(prop(&s, env, "lightOptions/source").as_layer(), None, "empty: the comp's Environment Layer");
|
||||
s.execute("prop.set", json!({"layer": env, "path": "lightOptions/source", "value": sky})).unwrap();
|
||||
assert_eq!(prop(&s, env, "lightOptions/source").as_layer(), Some(sky));
|
||||
s.undo();
|
||||
assert_eq!(prop(&s, env, "lightOptions/source").as_layer(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn three_d_switch_undo_redo() {
|
||||
let mut s = session();
|
||||
|
||||
Reference in New Issue
Block a user