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

Draft for handling ignored validation warnings #591

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
7 changes: 6 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ <h2 class="title is-spaced">Display</h2>
<b-tab-item label="Validator" icon="video" class="tabItemScrollable tab-item">
<template #header>
<div @click="collapseActiveTab($event, 2)"
v-bind:style="[tabsHidden === false && activeTab === 2 ? {'height': '100%'} : {}]">
v-bind:style="[tabContent === false && activeTab === 2 ? {'height': '100%'} : {}]">
<!-- to get colored icons use: https://stackoverflow.com/a/43916743 -->
<div style="max-width:fit-content; margin-left: auto; margin-right: auto;" v-html="getValidationCounter()"></div>
<span
Expand All @@ -325,6 +325,11 @@ <h2 class="title is-spaced" v-bind:data="validationReport">glTF Validator</h2>
<p>Number of warnings: {{validationReport?.issues?.numWarnings ?? 0}}</p>
<p>Number of infos: {{validationReport?.issues?.numInfos ?? 0}}</p>
</div>

<div v-show='validationReportDescription?.message !== undefined && validationReportDescription?.message !== ""'>
<p style="margin-top: 10px; margin-bottom: 10px; font-size:smaller;">{{validationReportDescription?.message}}</p>
</div>

<button class="button is-rounded" style="width: fit-content; flex-shrink: 0; margin-bottom: 12px;" v-on:click="copyToClipboard(JSON.stringify(validationReport, undefined, 4))">Copy</button>
<button class="button is-rounded" style="width: fit-content; flex-shrink: 0;" v-on:click="downloadJSON(validationReport?.uri?.substring(validationReport.uri.lastIndexOf('/') + 1) + '.report.json', validationReport)">Download</button>
<span style="margin-top: 5px;">Powered by <a href="https://github.com/KhronosGroup/glTF-Validator" target="_blank" rel="noopener noreferrer">glTF-Validator</a></span>
Expand Down
46 changes: 45 additions & 1 deletion src/logic/uimodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,53 @@ class UIModel
);
}

/**
* Creates a descriptive summary of the given validation report.
*
* If there are no issues, messages, or warnings in the given
* report, then an empty object is returned.
*
* Otherwise, the result will be an object that contains
* `numIgnoredWarnings:number` that counts the number of warnings
* that are ignored by the sample viewer, and a `message:string`
* that explains why these warnings are ignored.
*
* @param {any} validationReport The glTF validator validation report
* @returns The description
*/
createValidationReportDescription(validationReport) {
const issues = validationReport?.issues;
const messages = issues?.messages;
const numWarnings = issues?.numWarnings ?? 0;
if (!issues || !messages || numWarnings === 0) {
return {};
}
let numIgnoredWarnings = 0;
for (const message of messages) {
if (message.code === "MESH_PRIMITIVE_GENERATED_TANGENT_SPACE") {
numIgnoredWarnings++;
}
}
if (numIgnoredWarnings === 0) {
return {};
}
return {
numIgnoredWarnings: numIgnoredWarnings,
message: `The validation generated ${issues.numWarnings} warnings. `
+`${numIgnoredWarnings} of these warnings have been about missing `
+`tangent space information. Omitting the tangent space information `
+`may be a conscious decision by the designer, but it may limit `
+`the portability of the asset. The glTF-Sample-Viewer generates `
+`tangents using the default MikkTSpace algorithm in this case.`
};
}

updateValidationReport(validationReportObservable)
{
validationReportObservable.subscribe(data => this.app.validationReport = data);
validationReportObservable.subscribe(data => {
this.app.validationReport = data;
this.app.validationReportDescription = this.createValidationReportDescription(data);
});
}

disabledAnimations(disabledAnimationsObservable)
Expand Down
11 changes: 2 additions & 9 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ import {

import {validateBytes} from "gltf-validator";

const ignoredIssues = [
// This sample renderer supports tangent space generation.
"MESH_PRIMITIVE_GENERATED_TANGENT_SPACE"
];

export default async () => {
const canvas = document.getElementById("canvas");
const context = canvas.getContext("webgl2", {
Expand Down Expand Up @@ -75,8 +70,7 @@ export default async () => {
const buffer = await response.arrayBuffer();
return await validateBytes(new Uint8Array(buffer), {
externalResourceFunction: externalRefFunction,
uri: model.mainFile,
ignoredIssues
uri: model.mainFile
});
} else if (Array.isArray(model.mainFile)) {
const externalRefFunction = (uri) => {
Expand Down Expand Up @@ -106,8 +100,7 @@ export default async () => {
return await validateBytes(new Uint8Array(buffer),
{
externalResourceFunction: externalRefFunction,
uri: model.mainFile[0],
ignoredIssues
uri: model.mainFile[0]
});
}
} catch (error) {
Expand Down
75 changes: 61 additions & 14 deletions src/ui/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const appCreated = createApp({
disabledAnimations: [],

validationReport: {},
validationReportDescription: {},

ibl: true,
iblIntensity: 0.0,
Expand Down Expand Up @@ -222,25 +223,71 @@ const appCreated = createApp({
element.click();
document.body.removeChild(element);
},
getValidationCounter: function(){
let number = 0;

/**
* Creates a div string summarizing the given issues.
*
* If the given issues are empty or do not contain any errors,
* warnings, or infos, then the empty string is returned.
*
* Otherwise, the div contains the number of errors/warnings/infos
* with an appropriate background color. When all warnings of
* the given report are ignored, then this will only be a
* small "info" div. Clicking on that will expand the details
* about the ignored warnings.
*
* @param {any} issues The `issues` property that is part of
* the validation report of the glTF Validator
* @returns The div string
*/
getValidationInfoDiv : function(issues) {
if (!issues) {
return "";
}
let info = "";
let color = "white";
if (this.validationReport?.issues?.numErrors > 0) {
number = this.validationReport?.issues?.numErrors;
if (issues.numErrors > 0) {
info = `${issues.numErrors}`;
color = "red";
} else if (this.validationReport?.issues?.numWarnings > 0) {
number = this.validationReport?.issues?.numWarnings;
color = "yellow";
} else if (this.validationReport?.issues?.numInfos > 0) {
number = this.validationReport?.issues?.numInfos;
} else if (issues.numWarnings > 0) {
const allIgnored = issues.numWarnings ===
this.validationReportDescription?.numIgnoredWarnings;
if (allIgnored) {
info = "i";
color = "lightBlue";
} else {
info = `${issues.numWarnings}`;
color = "yellow";
}
} else if (issues.numInfos > 0) {
info = `${issues.numInfos}`;
}
if (number !== 0) {
return `<div style="display:flex;color:black; font-weight:bold; background-color:${color}; border-radius:50%; width:fit-content; min-width:2rem; align-items:center;aspect-ratio:1/1;justify-content:center;">${number}</div>`;
if (info.length > 3) {
info = "999+";
}
if (this.tabsHidden === false && this.activeTab === 2) {
return `<img src="assets/ui/Capture 50X50.svg" width="50px" height="100%">`;
if (info === "") {
return "";
}
const padding = this.isMobile ? "right:-3px;top:-18px;" : "right:-18px;top:-18px;";
const infoDiv =
`<div style="display:flex;color:black; position:absolute; ${padding} ` +
`font-size:80%; font-weight:bold; background-color:${color}; border-radius:50%; width:fit-content; ` +
`min-width:2rem; align-items:center;aspect-ratio:1/1;justify-content:center;">${info}</div>`;
return infoDiv;
},

getValidationCounter: function(){
const infoDiv = this.getValidationInfoDiv(this.validationReport?.issues);
if (this.tabContentHidden === false && this.activeTab === 2) {
return `<div style="position:relative; width:50px; height:100%">`
+ `<img src="assets/ui/Capture 50X50.svg" width="50px" height="100%">`
+ infoDiv
+ `</div>`;
}
return '<img src="assets/ui/Capture 30X30.svg" width="30px">';
return `<div style="position:relative; width:50px; height:100%">`
+ `<img src="assets/ui/Capture 30X30.svg" width="30px">`
+ infoDiv
+ `</div>`;
},
setAnimationState: function(value)
{
Expand Down