Преглед изворни кода

Examples ui improvement, add envMapRotation to RootScene ui, fix serialization with Object3DWidgetsPlugin, setDirty on enabled toggle in TonemapPlugin, add onChangeParams to bindToValue

master
Palash Bansal пре 1 година
родитељ
комит
f02d32c2dc
No account linked to committer's email address

+ 11
- 2
examples/glb-draco-export/script.ts Прегледај датотеку

@@ -1,12 +1,21 @@
import {_testFinish, downloadBlob, IObject3D, LoadingScreenPlugin, ThreeViewer} from 'threepipe'
import {_testFinish, AssetExporterPlugin, downloadBlob, IObject3D, LoadingScreenPlugin, ThreeViewer} from 'threepipe'
import {createSimpleButtons} from '../examples-utils/simple-bottom-buttons.js'
import {GLTFDracoExportPlugin} from '@threepipe/plugin-gltf-transform'

const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas') as HTMLCanvasElement, msaa: true})
const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
dropzone: {
addOptions: {
disposeSceneObjects: true,
},
},
msaa: true,
})

async function init() {

viewer.addPluginSync(LoadingScreenPlugin)
viewer.addPluginSync(AssetExporterPlugin)
viewer.addPluginSync(GLTFDracoExportPlugin)

// Note: see asset-exporter-plugin example as well

+ 50
- 18
examples/index.html Прегледај датотеку

@@ -15,16 +15,32 @@
}

:root {
--primary-color: #58a6ff;
//--primary-color: #58a6ff;
--primary-color: #6d7a8c;
//--primary-color: #ccdef5;
//--primary-color: #ec630a;
--secondary-color: #ec630a;
//--background-color: #1a1a1c;
--background-color: #1B1B1F;
--background-color: #E7EFF8;
--background-color-search: #dae1ea;
--background-color-search-hover: #c3d4e7;
//--text-color: #bbb;
--text-color: #DFDFD6;
--text-color-accent: #eee;
--text-color-hover: #fff;
--text-color: #1C2026;
--text-color-accent: #2b313a;
--text-color-hover: #2b313a;
}

@media (prefers-color-scheme: light) {
:root {
--primary-color: #b6bfcb;
--secondary-color: #ec630a;
--background-color: #1C2026;
--background-color-search: #3e4550;
--background-color-search-hover: #555e6b;
--text-color: #F6F7F9;
--text-color-accent: #d2d3d5;
--text-color-hover: #d2d3d5;
}
}

.root-container {
@@ -43,6 +59,7 @@
font-size: 1.75rem;
padding: 0.5rem;
color: var(--text-color);
cursor: pointer;
}

.hamburger:hover {
@@ -50,7 +67,7 @@
}

.sidebar {
max-width: min(320px, 30%);
width: min(320px, 30%);
height: 100%;
background: var(--background-color);
color: var(--text-color);
@@ -61,10 +78,11 @@
flex-direction: column;
gap: 0.5rem;
position: relative;
transition: width 0s ease-in-out;
}

.sidebar h1 {
color: #ddd;
color: var(--text-color);
font-size: 1.5rem;
margin: 0 3rem 1rem 0;
font-weight: normal;
@@ -72,7 +90,10 @@
}

.sidebar h1 a {
color: var(--secondary-color);
//background: linear-gradient(to right, rgb(231, 7, 7), rgb(91, 34, 203), rgb(7, 108, 211));
background: linear-gradient(to right, var(--secondary-color), var(--secondary-color), rgb(231, 7, 7));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-decoration: none;
}

@@ -83,7 +104,7 @@
.sidebar h2 {
font-size: 1.2rem;
margin: 0 0 0.5rem 0.25rem;
font-weight: normal;
font-weight: 500;
padding: 0;
}

@@ -102,7 +123,13 @@
color: var(--primary-color);
text-underline-offset: 0.25rem;
text-decoration: none;
transition: color 0.25s ease-in-out;
font-weight: 500;
transition: color 0.3s ease-in-out, font-weight 0.3s ease-in-out, background-size 0.75s;
background: linear-gradient(to right, rgb(231, 7, 7), rgb(91, 34, 203), rgb(7, 108, 211));
background-position: 0 100%;
background-repeat: no-repeat;
background-size: 0 0;
padding-bottom: 2px;
}

.sidebar ul li a:hover {
@@ -112,7 +139,8 @@
.sidebar ul li a.selected {
color: var(--text-color-hover);
font-weight: bold;
text-decoration: underline;
background-size: 100% 0.1em;
//text-decoration: underline;
}

.iframe-container {
@@ -141,6 +169,8 @@

.closed.sidebar{
padding: 1.75rem;
width: 3.3rem;
transition: width 0.3s ease-in-out;
}
.closed:before{
content: attr(data-selected-example);
@@ -156,6 +186,8 @@
line-height: 3.25rem;
writing-mode: vertical-lr;
text-orientation: upright;
text-transform: uppercase;
font-family: "Source Code Pro", Menlo, Courier, monospace;
}

.closed > .search-bar {
@@ -172,29 +204,29 @@
box-sizing: border-box;
width: 100%;
padding: 0.5rem;
color: var(--text-color);
background: #1e1e20;
color: var(--text-color-accent);
background: var(--background-color-search);
border: none;
border-radius: 4px;
transition: all 0.3s ease-in-out;
}
.search-bar input:hover {
background: #2a2a2c;
background: var(--background-color-search-hover);
}
.search-bar input:focus {
background: #2a2a2c;
background: var(--background-color-search-hover);
color: var(--text-color-hover);
outline: none;
}
.search-bar input::placeholder {
color: #888;
color: var(--primary-color);
}
.search-icon {
position: absolute;
top: 50%;
left: 10px;
transform: translateY(-50%);
color: #888;
color: var(--primary-color);
width: 15px;
height: 15px;
}
@@ -208,7 +240,7 @@
flex-direction: column;
}
.sidebar{
max-width: 100%;
width: 100%;
height: auto;
max-height: 50%;
padding: 1rem;

+ 1
- 1
examples/tweakpane-editor/script.ts Прегледај датотеку

@@ -125,7 +125,7 @@ async function init() {
BlendLoadPlugin,
HierarchyUiPlugin,
GeometryGeneratorPlugin,
Object3DWidgetsPlugin,
new Object3DWidgetsPlugin(false),
Object3DGeneratorPlugin,
GaussianSplattingPlugin,
ContactShadowGroundPlugin,

+ 21
- 6
src/core/object/RootScene.ts Прегледај датотеку

@@ -10,7 +10,7 @@ import {
} from 'three'
import type {IObject3D, IObjectProcessor} from '../IObject'
import {type ICamera} from '../ICamera'
import {Box3B} from '../../three'
import {bindToValue, Box3B} from '../../three'
import {AnyOptions, onChange2, onChange3, serialize} from 'ts-browser-helpers'
import {PerspectiveCamera2} from '../camera/PerspectiveCamera2'
import {ThreeSerialization} from '../../utils'
@@ -54,21 +54,36 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I
@uiSlider('Background Intensity', [0, 10], 0.01)
backgroundIntensity = 1

/**
* The default environment map used when rendering materials in the scene
*/
@uiImage('Environment')
@serialize() @onChange2(RootScene.prototype._onEnvironmentChange)
environment: ITexture | null = null

/**
* Extra textures/envmaps that can be used by objects/materials/plugins and will be serialized.
*/
@serialize()
public textureSlots: Record<string, ITexture> = {}
/**
* The intensity for the environment light.
*/
@uiSlider('Environment Intensity', [0, 10], 0.01)
@serialize() @onChange3(RootScene.prototype.setDirty)
envMapIntensity = 1

/**
* Rotation in radians of the default environment map.
* Same as {@link environment}.rotation.
*
* Note - this is not serialized here, but inside the texture.
*/
@uiSlider('Environment Rotation', [-Math.PI, Math.PI], 0.01)
@bindToValue({obj: 'environment', key: 'rotation', onChange: RootScene.prototype.setDirty, onChangeParams: false})
envMapRotation = 0

/**
* Extra textures/envmaps that can be used by objects/materials/plugins and will be serialized.
*/
@serialize()
public textureSlots: Record<string, ITexture> = {}

/**
* Fixed direction environment reflections irrespective of camera position.
*/

+ 1
- 1
src/plugins/extras/Object3DWidgetsPlugin.ts Прегледај датотеку

@@ -44,7 +44,7 @@ export class Object3DWidgetsPlugin extends AViewerPluginSync<''> {
onAdded(viewer: ThreeViewer) {
super.onAdded(viewer)
viewer.scene.addEventListener('addSceneObject', this._addSceneObject)
viewer.scene.addObject(this._widgetRoot)
viewer.scene.addObject(this._widgetRoot, {addToRoot: true, autoScale: false, autoCenter: false})
}
onRemove(viewer: ThreeViewer) {
viewer.scene.removeEventListener('addSceneObject', this._addSceneObject)

+ 4
- 1
src/plugins/postprocessing/TonemapPlugin.ts Прегледај датотеку

@@ -48,7 +48,10 @@ export class TonemapPlugin extends AScreenPassExtensionPlugin<''> {
['TONEMAP_BACKGROUND']: '1',
} as const

@serialize() @uiToggle('Enabled') enabled = true
@serialize()
@onChange(TonemapPlugin.prototype.setDirty)
@uiToggle('Enabled')
enabled = true

@uiDropdown('Mode', ([
['Linear', LinearToneMapping],

+ 5
- 2
src/three/utils/decorators.ts Прегледај датотеку

@@ -128,10 +128,11 @@ export function matDefineBool(key?: string|symbol, customDefines?: any, thisMat
* @param obj - object to bind to. If a string, it is used as a property name in `this`. If a function, it is called and the result is used as the object/string.
* @param key - key to bind to. If a string, it is used as a property name in `this`. If a function, it is called and the result is used as the key/string.
* @param onChange - function to call when the value changes. If a string, it is used as a property name in `this` and called. If a function, it is called. The function is called with the following parameters: key, newVal
* @param onChangeParams - if true, the parameters passed to the onChange function are [key, newVal]. If false, no parameters are passed. Default = `true`
* @param processVal - function that processes the value before setting it.
* @param invProcessVal - function that processes the value before returning it.
*/
export function bindToValue({obj, key, onChange, processVal, invProcessVal}: {obj?: ValOrFunc<any>, key?: ValOrFunc<string | symbol>, onChange?: ((...args: any[]) => any)|string, processVal?: (newVal: any) => any, invProcessVal?: (val: any) => any}): PropertyDecorator {
export function bindToValue({obj, key, processVal, invProcessVal, onChange, onChangeParams = true}: {obj?: ValOrFunc<any>, key?: ValOrFunc<string | symbol>, onChange?: ((...args: any[]) => any)|string, processVal?: (newVal: any) => any, invProcessVal?: (val: any) => any, onChangeParams?: boolean}): PropertyDecorator {
const cPropKey = !!key

return (targetPrototype: any, propertyKey: string|symbol, descriptor?: TypedPropertyDescriptor<any>) => {
@@ -144,18 +145,20 @@ export function bindToValue({obj, key, onChange, processVal, invProcessVal}: {ob
const prop = {
get() {
const {t, p} = getTarget(this)
if (!t || typeof t !== 'object') return
let res = t[p]
if (invProcessVal) res = invProcessVal(res)
return res
},
set(newVal: any) {
const {t, p} = getTarget(this)
if (!t || typeof t !== 'object') return
if (processVal) newVal = processVal(newVal)
safeSetProperty(t, p, newVal, true)
if (newVal === undefined) delete t[p]
let oc = onChange
if (oc && (typeof oc === 'string' || typeof oc === 'symbol')) oc = this[oc] // todo just call it here directly
if (oc && typeof oc === 'function') FnCaller.callFunction(oc, this, [p, newVal])
if (oc && typeof oc === 'function') FnCaller.callFunction(oc, this, onChangeParams ? [p, newVal] : [])
},
// configurable: true,
// enumerable: true,

Loading…
Откажи
Сачувај