Skip to content
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
6 changes: 5 additions & 1 deletion examples/jsm/exporters/GLTFExporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,8 @@ class GLTFWriter {
onlyVisible: true,
maxTextureSize: Infinity,
animations: [],
includeCustomExtensions: false
includeCustomExtensions: false,
copyright: null
}, options );

if ( this.options.animations.length > 0 ) {
Expand Down Expand Up @@ -687,6 +688,8 @@ class GLTFWriter {
// Update bytelength of the single buffer.
if ( json.buffers && json.buffers.length > 0 ) json.buffers[ 0 ].byteLength = blob.size;

if ( options.copyright ) json.asset.copyright = options.copyright;

if ( options.binary === true ) {

// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
Expand Down Expand Up @@ -3833,6 +3836,7 @@ GLTFExporter.Utils = {
* @property {Array<AnimationClip>|Array<Array<AnimationClip>>} [animations=[]] - List of animations to be included in the export. When exporting a single 3D object or scene, this is a flat list of clips.
* When exporting an array of multiple scenes, this must be a nested array with one list of clips per scene, matched to the input by index.
* @property {boolean} [includeCustomExtensions=false] - Export custom glTF extensions defined on an object's `userData.gltfExtensions` property.
* @property {string} [copyright=null] - Export with a copyright notice embedded in the glTF.
**/

/**
Expand Down
30 changes: 30 additions & 0 deletions examples/jsm/inspector/Inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,20 @@ class Inspector extends RendererInspector {

}

setVisible( value ) {

this.domElement.style.display = value ? '' : 'none';

return this;

}

getVisible() {

return this.domElement.style.display !== 'none';

}

getSize() {

return this.profiler.getSize();
Expand All @@ -149,6 +163,22 @@ class Inspector extends RendererInspector {

}

setHorizontalAlign( value ) {

this.profiler.setHorizontalAlign( value );

return this;

}

setVerticalAlign( value ) {

this.profiler.setVerticalAlign( value );

return this;

}

addTab( tab ) {

this.profiler.addTab( tab );
Expand Down
113 changes: 105 additions & 8 deletions examples/jsm/inspector/ui/Profiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ export class Profiler extends EventDispatcher {
this.maxZIndex = 1002; // Track the highest z-index for detached windows (starts at base z-index from CSS)
this.nextTabOriginalIndex = 0; // Track the original order of tabs as they are added

this.horizontalAlign = 'right'; // 'left' or 'right'
this.verticalAlign = 'top'; // 'top' or 'bottom'

this.setupShell();
this.setupResizing();

Style.init( this.domElement );

this.updateWidgetPosition();

// Setup window resize listener and update mobile status
this.setupWindowResizeListener();

Expand Down Expand Up @@ -495,20 +500,22 @@ export class Profiler extends EventDispatcher {
// Maximize based on current position
if ( this.position === 'bottom' ) {

this.panel.style.height = '100vh';
this.panel.style.height = '100%';
this.panel.style.width = '100%';

} else if ( this.position === 'right' ) {

this.panel.style.height = '100%';
this.panel.style.width = '100vw';
this.panel.style.width = '100%';

}

this.maximizeBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="8" y="8" width="12" height="12" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path></svg>';

}

this.updateWidgetPosition();

this.dispatchEvent( { type: 'resize' } );

}
Expand Down Expand Up @@ -1691,6 +1698,8 @@ export class Profiler extends EventDispatcher {

}

this.updateWidgetPosition();

this.dispatchEvent( { type: 'resize' } );

this.saveLayout();
Expand Down Expand Up @@ -1723,8 +1732,6 @@ export class Profiler extends EventDispatcher {
// Apply right position styles
this.panel.classList.remove( 'position-bottom' );
this.panel.classList.add( 'position-right' );
this.toggleButton.classList.add( 'position-right' );
this.miniPanel.classList.add( 'position-right' );
this.panel.style.bottom = '';
this.panel.style.top = '0';
this.panel.style.right = '0';
Expand All @@ -1733,7 +1740,7 @@ export class Profiler extends EventDispatcher {
// Apply size based on maximized state
if ( isMaximized ) {

this.panel.style.width = '100vw';
this.panel.style.width = '100%';
this.panel.style.height = '100%';

} else {
Expand All @@ -1753,8 +1760,6 @@ export class Profiler extends EventDispatcher {
// Apply bottom position styles
this.panel.classList.remove( 'position-right' );
this.panel.classList.add( 'position-bottom' );
this.toggleButton.classList.remove( 'position-right' );
this.miniPanel.classList.remove( 'position-right' );
this.panel.style.top = '';
this.panel.style.right = '';
this.panel.style.bottom = '0';
Expand All @@ -1764,7 +1769,7 @@ export class Profiler extends EventDispatcher {
if ( isMaximized ) {

this.panel.style.width = '100%';
this.panel.style.height = '100vh';
this.panel.style.height = '100%';

} else {

Expand All @@ -1775,6 +1780,8 @@ export class Profiler extends EventDispatcher {

}

this.updateWidgetPosition();

// Re-enable transition after a brief delay
setTimeout( () => {

Expand Down Expand Up @@ -2117,4 +2124,94 @@ export class Profiler extends EventDispatcher {

}

setHorizontalAlign( value ) {

this.horizontalAlign = value;
this.updateWidgetPosition();

return this;

}

setVerticalAlign( value ) {

this.verticalAlign = value;
this.updateWidgetPosition();

return this;

}

updateWidgetPosition() {

const isVisible = this.panel.classList.contains( 'visible' );
const isMaximized = this.panel.classList.contains( 'maximized' );
const isRight = this.position === 'right';

let horizontal = this.horizontalAlign; // 'left' or 'right'
let vertical = this.verticalAlign; // 'top' or 'bottom'

if ( isVisible ) {

if ( isRight ) {

// If panel is open on the right:
// Toggle should be on the opposite side of 'right' if default is 'right' to avoid overlapping the panel.
if ( this.horizontalAlign === 'right' ) {

horizontal = 'left';

}

} else {

// If panel is open at the bottom:
if ( ! isMaximized ) {

// If default is bottom, we must move to top to avoid overlapping the panel at the bottom.
if ( this.verticalAlign === 'bottom' ) {

vertical = 'top';

}

} else {

// If maximized, move to the opposite vertical position to avoid overlap with header/tabs.
vertical = this.verticalAlign === 'top' ? 'bottom' : 'top';

}

}

}

// Apply horizontal class
if ( horizontal === 'left' ) {

this.toggleButton.classList.add( 'toggle-left' );
this.miniPanel.classList.add( 'toggle-left' );

} else {

this.toggleButton.classList.remove( 'toggle-left' );
this.miniPanel.classList.remove( 'toggle-left' );

}

// Apply vertical class
if ( vertical === 'bottom' ) {

this.toggleButton.classList.add( 'toggle-bottom' );
this.miniPanel.classList.add( 'toggle-bottom' );

} else {

this.toggleButton.classList.remove( 'toggle-bottom' );
this.miniPanel.classList.remove( 'toggle-bottom' );

}

}

}
48 changes: 27 additions & 21 deletions examples/jsm/inspector/ui/Style.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ export class Style {
--color-call: rgba(255, 185, 34, 1);
--font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
--font-mono: 'Courier New', Courier, monospace;

position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1000;
}

:scope * {
pointer-events: auto;
}

.profiler-panel, .profiler-toggle, .detached-tab-panel,
Expand All @@ -33,7 +45,7 @@ export class Style {
}

.profiler-toggle {
position: fixed;
position: absolute;
top: 15px;
right: 15px;
background-color: rgba(30, 30, 36, 0.85);
Expand Down Expand Up @@ -68,14 +80,14 @@ export class Style {
opacity: 0.5;
}

.profiler-toggle.position-right.panel-open {
.profiler-toggle.toggle-left {
right: auto;
left: 15px;
border-radius: 6px 12px 12px 6px;
flex-direction: row-reverse;
}

.profiler-toggle.position-right.panel-open .builtin-tabs-container {
.profiler-toggle.toggle-left .builtin-tabs-container {
border-right: none;
border-left: 1px solid #262636;
}
Expand Down Expand Up @@ -227,7 +239,7 @@ export class Style {
}

.profiler-mini-panel {
position: fixed;
position: absolute;
top: 60px;
right: 15px;
background-color: rgba(30, 30, 36, 0.85);
Expand All @@ -252,7 +264,7 @@ export class Style {
transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.profiler-mini-panel.position-right.panel-open {
.profiler-mini-panel.toggle-left {
right: auto;
left: 15px;
}
Expand All @@ -263,20 +275,14 @@ export class Style {
transform: translateY(0) scale(1);
}

/* Position toggle and mini-panel at the bottom when maximized */
:scope:has(.profiler-panel.maximized) .profiler-toggle,
:scope.maximized .profiler-toggle {
top: auto !important;
bottom: 15px !important;
z-index: 10005 !important;
.profiler-toggle.toggle-bottom {
top: auto;
bottom: 15px;
}

:scope:has(.profiler-panel.maximized) .profiler-mini-panel,
:scope.maximized .profiler-mini-panel {
top: auto !important;
bottom: 60px !important;
max-height: calc(100vh - 120px) !important;
z-index: 10006 !important;
.profiler-mini-panel.toggle-bottom {
top: auto;
bottom: 60px;
}

.profiler-mini-panel::-webkit-scrollbar {
Expand Down Expand Up @@ -560,7 +566,7 @@ export class Style {
}

.profiler-panel {
position: fixed;
position: absolute;
z-index: 1001 !important;
bottom: 0;
left: 0;
Expand Down Expand Up @@ -589,7 +595,7 @@ export class Style {
}

.profiler-panel.maximized {
height: 100vh;
height: 100%;
}

/* Position-specific styles */
Expand Down Expand Up @@ -1689,7 +1695,7 @@ export class Style {
}

.drag-preview-indicator {
position: fixed;
position: absolute;
background-color: rgba(0, 170, 255, 0.2);
border: 2px dashed var(--color-accent);
z-index: 999;
Expand All @@ -1699,7 +1705,7 @@ export class Style {

/* Detached Tab Windows */
.detached-tab-panel {
position: fixed;
position: absolute;
width: 500px;
height: 400px;
background: var(--profiler-background);
Expand Down