Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Target emissive control #369

Merged
merged 4 commits into from
May 25, 2022
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
1 change: 1 addition & 0 deletions docs/experimentConfigReadme.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ The following configuration is universal to all target types.
* `visualSize` is a vector indicating the minimum ([0]) and maximum ([1]) visual size for the target (in deg)
* `colors` is an array of 2 colors (max and min health) which are interpolated between based on target damage (note this setting overrides the experiment or session-level [`targetHealthColors`](general_config.md#target-rendering) setting). If unspecified the experiment/session level settings are used.
* `gloss` is a `Color4` representing glossyness, the first 3 channels are RGB w/ alpha representing minimum reflection (F0). Set all channels to 0 or do not specify to disable glossy reflections (note this setting overrides the experiment or session-level [`targetGloss`](general_config.md#target-rendering) setting). If unspecified the experiment/session level settings are used.
* `emissive` is an array of 2 colors (max and min health) which are interpolated between based on the target damage (note this setting overrides the experiment or session-level [`targetEmissive`](general_config.md#target-rendering) setting). If unspecified the experiment/session level settings are used.
* `destSpace` the space for which the target is rendered (useful for non-destiantion based targets, "player" or "world")
* `hitSound` is a filename for the sound to play when the target is hit but not destroyed (for no sound use an empty string).
* `hitSoundVol` provides the volume (as a float) for the hit sound to be played at (default is `1.0`).
Expand Down
5 changes: 5 additions & 0 deletions docs/general_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ These flags help control the behavior of click-to-photon monitoring in applicati
|-----------------------|-----------------------|------------------------------------------------------------------------------------|
|`targetHealthColors` |[`Color3`, `Color3`] | The max/min health colors for the target as an array of [`max color`, `min color`], if you do not want the target to change color as its health drops, set these values both to the same color |
|`targetGloss` |`Color4` | The target glossy (reflection) value, first 3 channels are RGB w/ alpha representing minimum reflection (F0). Set all channels to 0 or do not specify to disable glossy reflections. This sets the glossy color for the reference target in addition to trial targets |
|`targetEmissive` |[`Color4`, `Color4`] | The max/min health emissive colors for the target as an array of [`max color`, `min color`], if you do not want the target to change color as its health drops set the values both to the same color. If no value is specified a default of 0.7 * the target color is used to match historical behavior. |
|`showReferenceTarget` |`bool` | Show a reference target to re-center the view between trials/sessions? |
|`referenceTargetColor` |`Color3` | The color of the "reference" targets spawned between trials |
|`referenceTargetSize` |m | The size of the "reference" targets spawned between trials |
Expand Down Expand Up @@ -542,6 +543,10 @@ These flags help control the behavior of click-to-photon monitoring in applicati
"showReferenceTargetMissDecals" : true, // Show miss decals for reference targets
"previewTargetColor" = Color3(0.5, 0.5, 0.5), // Use gray for preview targets (if they are shown)
"targetGloss" = Color4(0.4f, 0.2f, 0.1f, 0.8f), // Use the target gloss behavior from FPSci v22.02.01 and earlier
"targetEmissive" = [
Color4(0, 0.7, 0, 1);
Color4(0.7, 0, 0, 1);
],
```

### Target Health Bars
Expand Down
25 changes: 19 additions & 6 deletions source/FPSciApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,31 +273,44 @@ Array<shared_ptr<UniversalMaterial>> FPSciApp::makeMaterials(shared_ptr<TargetCo
Array<shared_ptr<UniversalMaterial>> targetMaterials;
for (int i = 0; i < matTableSize; i++) {
float complete = (float)i / (matTableSize-1);
Color3 color;

Color4 color;
if (notNull(tconfig) && tconfig->colors.length() > 0) {
color = lerpColor(tconfig->colors, complete);
}
else {
color = lerpColor(experimentConfig.targetView.healthColors, complete);
color = lerpColor(sessConfig->targetView.healthColors, complete);
}

Color4 gloss;
if (notNull(tconfig) && tconfig->hasGloss) {
gloss = tconfig->gloss;
}
else {
gloss = experimentConfig.targetView.gloss;
gloss = sessConfig->targetView.gloss;
}

Color4 emissive;
if (notNull(tconfig) && tconfig->emissive.length() > 0) {
emissive = lerpColor(tconfig->emissive, complete);
}
else if(sessConfig->targetView.emissive.length() > 0) {
emissive = lerpColor(sessConfig->targetView.emissive, complete);
}
else {
emissive = color * 0.7f; // Historical behavior fallback for unspecified case
}

UniversalMaterial::Specification materialSpecification;
materialSpecification.setLambertian(Texture::Specification(color));
materialSpecification.setEmissive(Texture::Specification(color * 0.7f));
materialSpecification.setEmissive(Texture::Specification(emissive));
materialSpecification.setGlossy(Texture::Specification(gloss)); // Used to be Color4(0.4f, 0.2f, 0.1f, 0.8f)
targetMaterials.append(UniversalMaterial::create(materialSpecification));
}
return targetMaterials;
}

Color3 FPSciApp::lerpColor(Array<Color3> colors, float a) {
Color4 FPSciApp::lerpColor(Array<Color4> colors, float a) {
if (colors.length() == 0) {
throw "Cannot interpolate from colors array with length 0!";
}
Expand All @@ -323,7 +336,7 @@ Color3 FPSciApp::lerpColor(Array<Color3> colors, float a) {
float interp = (1.0f - a) * (colors.length() - 1);
int idx = int(floor(interp));
interp = interp - float(idx);
Color3 output = colors[idx] * (1.0f - interp) + colors[idx + 1] * interp;
Color4 output = colors[idx] * (1.0f - interp) + colors[idx + 1] * interp;
return output;
}
}
Expand Down
2 changes: 1 addition & 1 deletion source/FPSciApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ class FPSciApp : public GApp {
const int matTableSize = 13; ///< Set this to set # of color "levels"

Array<shared_ptr<UniversalMaterial>> makeMaterials(shared_ptr<TargetConfig> tconfig);
Color3 lerpColor(Array<Color3> colors, float a);
Color4 lerpColor(Array<Color4> colors, float a);

shared_ptr<Session> sess; ///< Pointer to the experiment
shared_ptr<Camera> playerCamera; ///< Pointer to the player camera
Expand Down
4 changes: 4 additions & 0 deletions source/FpsConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ void TargetViewConfig::load(FPSciAnyTableReader reader, int settingsVersion) {
throw "Specified \"healthColors\" doesn't contain at least one Color3!";
}
reader.getIfPresent("targetGloss", gloss);
reader.getIfPresent("targetEmissive", emissive);
reader.getIfPresent("targetHealthBarColors", healthBarColors);
reader.getIfPresent("showFloatingCombatText", showCombatText);
reader.getIfPresent("floatingCombatTextSize", combatTextSize);
Expand Down Expand Up @@ -467,6 +468,8 @@ void TargetViewConfig::load(FPSciAnyTableReader reader, int settingsVersion) {

Any TargetViewConfig::addToAny(Any a, bool forceAll) const {
TargetViewConfig def;
if (forceAll || def.gloss != gloss) a["targetGloss"] = gloss;
if (forceAll || def.emissive != emissive) a["targetEmissive"] = emissive;
if (forceAll || def.showHealthBars != showHealthBars) a["showTargetHealthBars"] = showHealthBars;
if (forceAll || def.healthBarSize != healthBarSize) a["targetHealthBarSize"] = healthBarSize;
if (forceAll || def.healthBarOffset != healthBarOffset) a["targetHealthBarOffset"] = healthBarOffset;
Expand All @@ -486,6 +489,7 @@ Any TargetViewConfig::addToAny(Any a, bool forceAll) const {
if (forceAll || def.showRefTarget != showRefTarget) a["showRefTarget"] = showRefTarget;
if (forceAll || def.refTargetSize != refTargetSize) a["referenceTargetSize"] = refTargetSize;
if (forceAll || def.refTargetColor != refTargetColor) a["referenceTargetColor"] = refTargetColor;
if (forceAll || def.refTargetModelSpec != refTargetModelSpec) a["referenceTargetModelSpec"] = refTargetModelSpec;
if (forceAll || def.clearDecalsWithRef != clearDecalsWithRef) a["clearMissDecalsWithReference"] = clearDecalsWithRef;
if (forceAll || def.previewWithRef != previewWithRef) a["showPreviewTargetsWithReference"] = previewWithRef;
if (forceAll || def.showRefDecals != showRefDecals) a["showReferenceTargetMissDecals"] = showRefDecals;
Expand Down
5 changes: 3 additions & 2 deletions source/FpsConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,13 @@ class FeedbackConfig {
class TargetViewConfig {
public:
// Target color based on health
Array<Color3> healthColors = { ///< Target start/end color (based on target health)
Array<Color4> healthColors = { ///< Target start/end color (based on target health)
Color3(0.0, 1.0, 0.0),
Color3(1.0, 0.0, 0.0)
};

Color4 gloss; ///< Target glossyness (alpha is F0 or minimum reflectivity, see G3D docs)
Color4 gloss; ///< Target glossyness (alpha is F0 or minimum reflectivity, see G3D docs)
Array<Color4> emissive; ///< Target emissive color

// Target health bars
bool showHealthBars = false; ///< Display a target health bar?
Expand Down
1 change: 1 addition & 0 deletions source/TargetEntity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ TargetConfig::TargetConfig(const Any& any) {
reader.getIfPresent("destroyedSound", destroyedSound);
reader.getIfPresent("destroyedSoundVol", destroyedSoundVol);
reader.getIfPresent("colors", colors);
reader.getIfPresent("emissive", emissive);
hasGloss = reader.getIfPresent("gloss", gloss);

break;
Expand Down
3 changes: 2 additions & 1 deletion source/TargetEntity.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,10 @@ class TargetConfig : public ReferenceCountedObject {
float destroyedSoundVol = 1.0f;

// Target color based on health
Array<Color3> colors; ///< Target start/end color (based on target health)
Array<Color4> colors; ///< Target start/end color (based on target health)
Color4 gloss; ///< Target gloss (alpha is F0, see docs)
bool hasGloss = false; ///< Target has gloss specified
Array<Color4> emissive; ///< Target start/end emissive color (similar to colors above)

Any modelSpec = PARSE_ANY(ArticulatedModel::Specification{ ///< Basic model spec for target
filename = "model/target/low_poly_sphere.obj";
Expand Down