Move exposure slider, add wildcat

This commit is contained in:
Brian Beck 2024-01-28 17:56:38 -08:00
parent a02e9c1a4d
commit e628bb4b63
39 changed files with 182 additions and 88 deletions

View file

@ -28,7 +28,11 @@ const weaponModels = [
"targeting",
];
const vehicleModels = ["vehicle_air_scout", "vehicle_land_mpbbase"];
const vehicleModels = [
"vehicle_air_scout",
"vehicle_grav_scout",
"vehicle_land_mpbbase",
];
export async function getSkinConfig() {
const [defaultSkins, customSkins, customWeaponSkins] = await Promise.all([
@ -106,6 +110,7 @@ export async function getSkinConfig() {
// Vehicles
vehicle_air_scout: "vehicle_air_scout",
vehicle_land_mpbbase: "vehicle_land_mpbbase",
vehicle_grav_scout: "vehicle_grav_scout",
},
animationLabels: {
Forward: "Run Forward",
@ -292,6 +297,64 @@ export async function getSkinConfig() {
size: [256, 256],
},
],
vehicle_grav_scout: [
{
label: "Vehicle",
name: "Vehicle_grav_scout0",
file: "Vehicle_grav_scout",
size: [512, 256],
},
{
name: "Unassigned",
hidden: true,
hasDefault: false,
},
{
label: "Pipes",
name: "Vehicle_grav_scout_pipes1",
file: "Vehicle_grav_scout_pipes",
metallicFactor: 0,
roughnessFactor: 1,
},
{
name: "Vehicle_grav_scout",
hidden: true,
hasDefault: false,
},
{
label: "Side Thrusters",
name: "Vehicle_grav_scout_pipes",
file: "Vehicle_grav_scout_pipes",
emissiveFactor: [1, 1, 1],
alphaMode: "OPAQUE",
metallicFactor: 0,
roughnessFactor: 1,
emissiveTexture: true,
selectable: false,
},
{
label: "Windshield",
name: "Vehicle_grav_scout_windshield",
file: "Vehicle_grav_scout_windshield",
selectable: false,
alphaMode: "BLEND",
baseColorFactor: [1, 1, 1, 0.5],
metallicFactor: 0,
roughnessFactor: 1,
size: [128, 128],
},
{
label: "Windshield Inner",
name: "Vehicle_grav_scout_windshieldInner",
file: "Vehicle_grav_scout_windshieldInner",
selectable: false,
alphaMode: "BLEND",
baseColorFactor: [1, 1, 1, 0.5],
metallicFactor: 0,
roughnessFactor: 1,
size: [128, 128],
},
],
vehicle_land_mpbbase: [
{
label: "Vehicle Front",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,2 @@
!function(){"use strict";var e,t,n,r,o,u,i,c={},a={};function f(e){var t=a[e];if(void 0!==t)return t.exports;var n=a[e]={exports:{}},r=!0;try{c[e].call(n.exports,n,n.exports,f),r=!1}finally{r&&delete a[e]}return n.exports}f.m=c,e=[],f.O=function(t,n,r,o){if(n){o=o||0;for(var u=e.length;u>0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[n,r,o];return}for(var i=1/0,u=0;u<e.length;u++){for(var n=e[u][0],r=e[u][1],o=e[u][2],c=!0,a=0;a<n.length;a++)i>=o&&Object.keys(f.O).every(function(e){return f.O[e](n[a])})?n.splice(a--,1):(c=!1,o<i&&(i=o));if(c){e.splice(u--,1);var l=r();void 0!==l&&(t=l)}}return t},f.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(t,{a:t}),t},f.d=function(e,t){for(var n in t)f.o(t,n)&&!f.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},f.f={},f.e=function(e){return Promise.all(Object.keys(f.f).reduce(function(t,n){return f.f[n](e,t),t},[]))},f.u=function(e){return"static/chunks/"+(737===e?"fb7d5399":e)+"."+({70:"0ba1ca12d54bca2d",258:"53d25aa602c4d686",354:"3289d8281650c8de",737:"ddae1e8fed13bcfe",990:"4c85486f75efa465"})[e]+".js"},f.miniCssF=function(e){return"static/css/1c3a9dfba8410e18.css"},f.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),f.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t={},n="_N_E:",f.l=function(e,r,o,u){if(t[e]){t[e].push(r);return}if(void 0!==o)for(var i,c,a=document.getElementsByTagName("script"),l=0;l<a.length;l++){var s=a[l];if(s.getAttribute("src")==e||s.getAttribute("data-webpack")==n+o){i=s;break}}i||(c=!0,(i=document.createElement("script")).charset="utf-8",i.timeout=120,f.nc&&i.setAttribute("nonce",f.nc),i.setAttribute("data-webpack",n+o),i.src=f.tu(e)),t[e]=[r];var d=function(n,r){i.onerror=i.onload=null,clearTimeout(p);var o=t[e];if(delete t[e],i.parentNode&&i.parentNode.removeChild(i),o&&o.forEach(function(e){return e(r)}),n)return n(r)},p=setTimeout(d.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=d.bind(null,i.onerror),i.onload=d.bind(null,i.onload),c&&document.head.appendChild(i)},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.tt=function(){return void 0===r&&(r={createScriptURL:function(e){return e}},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(r=trustedTypes.createPolicy("nextjs#bundler",r))),r},f.tu=function(e){return f.tt().createScriptURL(e)},f.p="/t2-model-skinner/_next/",o={272:0},f.f.j=function(e,t){var n=f.o(o,e)?o[e]:void 0;if(0!==n){if(n)t.push(n[2]);else if(272!=e){var r=new Promise(function(t,r){n=o[e]=[t,r]});t.push(n[2]=r);var u=f.p+f.u(e),i=Error();f.l(u,function(t){if(f.o(o,e)&&(0!==(n=o[e])&&(o[e]=void 0),n)){var r=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;i.message="Loading chunk "+e+" failed.\n("+r+": "+u+")",i.name="ChunkLoadError",i.type=r,i.request=u,n[1](i)}},"chunk-"+e,e)}else o[e]=0}},f.O.j=function(e){return 0===o[e]},u=function(e,t){var n,r,u=t[0],i=t[1],c=t[2],a=0;if(u.some(function(e){return 0!==o[e]})){for(n in i)f.o(i,n)&&(f.m[n]=i[n]);if(c)var l=c(f)}for(e&&e(t);a<u.length;a++)r=u[a],f.o(o,r)&&o[r]&&o[r][0](),o[r]=0;return f.O(l)},(i=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(u.bind(null,0)),i.push=u.bind(null,i.push.bind(i))}();
//# sourceMappingURL=webpack-777e35b1f29a758f.js.map
!function(){"use strict";var e,t,n,r,o,u,i,c={},a={};function f(e){var t=a[e];if(void 0!==t)return t.exports;var n=a[e]={exports:{}},r=!0;try{c[e].call(n.exports,n,n.exports,f),r=!1}finally{r&&delete a[e]}return n.exports}f.m=c,e=[],f.O=function(t,n,r,o){if(n){o=o||0;for(var u=e.length;u>0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[n,r,o];return}for(var i=1/0,u=0;u<e.length;u++){for(var n=e[u][0],r=e[u][1],o=e[u][2],c=!0,a=0;a<n.length;a++)i>=o&&Object.keys(f.O).every(function(e){return f.O[e](n[a])})?n.splice(a--,1):(c=!1,o<i&&(i=o));if(c){e.splice(u--,1);var l=r();void 0!==l&&(t=l)}}return t},f.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(t,{a:t}),t},f.d=function(e,t){for(var n in t)f.o(t,n)&&!f.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},f.f={},f.e=function(e){return Promise.all(Object.keys(f.f).reduce(function(t,n){return f.f[n](e,t),t},[]))},f.u=function(e){return"static/chunks/"+(737===e?"fb7d5399":e)+"."+({70:"0ba1ca12d54bca2d",258:"53d25aa602c4d686",354:"3289d8281650c8de",737:"ddae1e8fed13bcfe",990:"4c85486f75efa465"})[e]+".js"},f.miniCssF=function(e){return"static/css/e741e79dc7c3ac9a.css"},f.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),f.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t={},n="_N_E:",f.l=function(e,r,o,u){if(t[e]){t[e].push(r);return}if(void 0!==o)for(var i,c,a=document.getElementsByTagName("script"),l=0;l<a.length;l++){var s=a[l];if(s.getAttribute("src")==e||s.getAttribute("data-webpack")==n+o){i=s;break}}i||(c=!0,(i=document.createElement("script")).charset="utf-8",i.timeout=120,f.nc&&i.setAttribute("nonce",f.nc),i.setAttribute("data-webpack",n+o),i.src=f.tu(e)),t[e]=[r];var d=function(n,r){i.onerror=i.onload=null,clearTimeout(p);var o=t[e];if(delete t[e],i.parentNode&&i.parentNode.removeChild(i),o&&o.forEach(function(e){return e(r)}),n)return n(r)},p=setTimeout(d.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=d.bind(null,i.onerror),i.onload=d.bind(null,i.onload),c&&document.head.appendChild(i)},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.tt=function(){return void 0===r&&(r={createScriptURL:function(e){return e}},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(r=trustedTypes.createPolicy("nextjs#bundler",r))),r},f.tu=function(e){return f.tt().createScriptURL(e)},f.p="/t2-model-skinner/_next/",o={272:0},f.f.j=function(e,t){var n=f.o(o,e)?o[e]:void 0;if(0!==n){if(n)t.push(n[2]);else if(272!=e){var r=new Promise(function(t,r){n=o[e]=[t,r]});t.push(n[2]=r);var u=f.p+f.u(e),i=Error();f.l(u,function(t){if(f.o(o,e)&&(0!==(n=o[e])&&(o[e]=void 0),n)){var r=t&&("load"===t.type?"missing":t.type),u=t&&t.target&&t.target.src;i.message="Loading chunk "+e+" failed.\n("+r+": "+u+")",i.name="ChunkLoadError",i.type=r,i.request=u,n[1](i)}},"chunk-"+e,e)}else o[e]=0}},f.O.j=function(e){return 0===o[e]},u=function(e,t){var n,r,u=t[0],i=t[1],c=t[2],a=0;if(u.some(function(e){return 0!==o[e]})){for(n in i)f.o(i,n)&&(f.m[n]=i[n]);if(c)var l=c(f)}for(e&&e(t);a<u.length;a++)r=u[a],f.o(o,r)&&o[r]&&o[r][0](),o[r]=0;return f.O(l)},(i=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(u.bind(null,0)),i.push=u.bind(null,i.push.bind(i))}();
//# sourceMappingURL=webpack-de3d8c0ccdef0b14.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
self.__BUILD_MANIFEST={__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":["static/chunks/78e521c3-312593b4f3190cc4.js","static/chunks/95b64a6e-6f3d919198a9be32.js","static/chunks/31664189-7261674e93dbb0a6.js","static/chunks/545f34e4-f96cf9e26b6b92a5.js","static/chunks/1bfc9850-6b316c8ef06e5170.js","static/chunks/d7eeaac4-06e64d251e2cbda7.js","static/chunks/f580fadb-a8e2c6896615a304.js","static/chunks/50-cece886aa17c1d5e.js","static/chunks/pages/index-5096828536898478.js"],"/_error":["static/chunks/pages/_error-479484f6c157e921.js"],sortedPages:["/","/_app","/_error"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
self.__BUILD_MANIFEST={__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":["static/chunks/78e521c3-312593b4f3190cc4.js","static/chunks/95b64a6e-6f3d919198a9be32.js","static/chunks/31664189-7261674e93dbb0a6.js","static/chunks/545f34e4-f96cf9e26b6b92a5.js","static/chunks/1bfc9850-6b316c8ef06e5170.js","static/chunks/d7eeaac4-06e64d251e2cbda7.js","static/chunks/f580fadb-a8e2c6896615a304.js","static/chunks/50-cece886aa17c1d5e.js","static/chunks/pages/index-0934afea379f1152.js"],"/_error":["static/chunks/pages/_error-479484f6c157e921.js"],sortedPages:["/","/_app","/_error"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

BIN
docs/vehicle_grav_scout.glb Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

View file

@ -0,0 +1,26 @@
import { ImBrightnessContrast } from "react-icons/im";
import useEnvironment from "./useEnvironment";
export default function EnvironmentExposure() {
const { exposure, setExposure } = useEnvironment();
return (
<>
<label htmlFor="EnvExposure">
<ImBrightnessContrast size={16} />
</label>
<input
aria-label="Exposure"
id="EnvExposure"
type="range"
min={0.2}
max={2.2}
step={0.1}
value={exposure}
onChange={(event) => {
setExposure(parseFloat(event.target.value));
}}
/>
</>
);
}

View file

@ -1,9 +1,7 @@
import { ImBrightnessContrast } from "react-icons/im";
import useEnvironment from "./useEnvironment";
export default function EnvironmentSelector() {
const { selectedEnvironment, setSelectedEnvironment, exposure, setExposure } =
useEnvironment();
const { selectedEnvironment, setSelectedEnvironment } = useEnvironment();
return (
<>
@ -31,23 +29,6 @@ export default function EnvironmentSelector() {
<option value="spruit_sunrise_1k_HDR.hdr">Spruit Sunrise</option>
<option value="umhlanga_sunrise_1k.hdr">Umhlanga Sunrise</option>
</select>
<div className="CheckboxField">
<label htmlFor="EnvExposure">
<ImBrightnessContrast size={16} />
</label>
<input
aria-label="Exposure"
id="EnvExposure"
type="range"
min={0.2}
max={2.2}
step={0.1}
value={exposure}
onChange={(event) => {
setExposure(parseFloat(event.target.value));
}}
/>
</div>
</>
);
}

View file

@ -20,6 +20,7 @@ export type MaterialDefinition = {
hasDefault?: boolean;
size?: [number, number];
hidden?: boolean;
selectable?: boolean;
alphaMode?: "BLEND" | "MASK" | "OPAQUE";
alphaCutoff?: number;
baseColorFactor?: [number, number, number, number];

View file

@ -20,7 +20,9 @@ export default function MaterialSelector() {
}}
>
{materialDefs.map((materialDef, i) =>
materialDef && !materialDef.hidden ? (
materialDef &&
!materialDef.hidden &&
materialDef.selectable !== false ? (
<option key={materialDef.name} value={i}>
{materialDef.label ?? materialDef.name}
</option>

View file

@ -344,7 +344,9 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
materialDefs
.filter(
(materialDef: MaterialDefinition) =>
materialDef && !materialDef.hidden
materialDef &&
!materialDef.hidden &&
materialDef.selectable !== false
)
.map(async (materialDef: MaterialDefinition) => {
const colorCanvas = canvases[`${materialDef.name}:color`]?.canvas;

View file

@ -86,6 +86,7 @@ export default function WarriorSelector() {
</optgroup>
<optgroup label="Vehicles" data-model-type="vehicle">
<option value="vehicle_air_scout">Shrike</option>
<option value="vehicle_grav_scout">Wildcat</option>
<option value="vehicle_land_mpbbase">MPB</option>
</optgroup>
</select>

View file

@ -9,6 +9,7 @@ import WarriorSelector from "../WarriorSelector";
import WarriorProvider from "../WarriorProvider";
import WarriorViewer from "../WarriorViewer";
import EnvironmentSelector from "../EnvironmentSelector";
import EnvironmentExposure from "../EnvironmentExposure";
import AnimationSelector from "../AnimationSelector";
import EnvironmentProvider from "../EnvironmentProvider";
import SkinProvider from "../SkinProvider";
@ -56,6 +57,9 @@ export default function HomePage() {
<div className="Field">
<EnvironmentSelector />
</div>
<div className="Field SliderField">
<EnvironmentExposure />
</div>
<div className="Field">
<AnimationSelector />
</div>

View file

@ -321,55 +321,6 @@ select {
color: #d0ffee;
}
@media only screen and (max-width: 899px) {
main {
flex-direction: column;
}
.Field {
padding: 0 10px;
}
.ModelTools {
position: static;
flex-direction: column;
}
.Viewport {
flex-direction: column;
align-items: center;
}
select {
max-width: calc(100vw - 20px);
}
.Toolbar {
flex-direction: column;
}
model-viewer {
min-width: 100vw;
min-height: 100vh;
}
.CanvasInteractions {
align-items: center;
padding-bottom: 50px;
}
.CanvasViewport {
display: none;
}
.CanvasTools {
display: none;
flex-direction: column;
align-items: center;
gap: 10px;
}
}
.CanvasContainer {
position: relative;
}
@ -429,9 +380,72 @@ h6 {
padding: 0;
}
.CheckboxField {
.SliderField {
font-size: 13px;
display: flex;
flex-direction: row;
align-items: center;
gap: 4px;
gap: 8px;
margin-top: 17px;
margin-right: auto;
}
.SliderField input[type="range"] {
width: 120px;
}
@media only screen and (max-width: 899px) {
main {
flex-direction: column;
}
.Field {
padding: 0 10px;
}
.ModelTools {
position: static;
flex-direction: column;
}
.Viewport {
flex-direction: column;
align-items: center;
}
select {
max-width: calc(100vw - 20px);
}
.Toolbar {
flex-direction: column;
}
model-viewer {
min-width: 100vw;
min-height: 100vh;
}
.CanvasInteractions {
align-items: center;
padding-bottom: 50px;
}
.CanvasViewport {
display: none;
}
.CanvasTools {
display: none;
flex-direction: column;
align-items: center;
gap: 10px;
}
.SliderField {
margin-top: 0;
}
.SliderField input[type="range"] {
width: 152px;
}
}