mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
show texture icon
This commit is contained in:
@@ -165,6 +165,124 @@
|
||||
width: 55% !important;
|
||||
}
|
||||
|
||||
/* Floatable Controls Panel */
|
||||
#controls-wrapper {
|
||||
position: absolute;
|
||||
top: 150px;
|
||||
right: 10px;
|
||||
z-index: 200;
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
|
||||
overflow: visible;
|
||||
min-width: 350px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
#controls-wrapper.minimized .lil-gui {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#controls-header {
|
||||
background: linear-gradient(135deg, #2196F3 0%, #1976D2 100%);
|
||||
color: white;
|
||||
padding: 8px 12px;
|
||||
cursor: move;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#controls-header:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
#controls-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
#controls-buttons {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.control-btn {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border: none;
|
||||
color: white;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.control-btn:hover {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.control-btn:active {
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
#controls-wrapper .lil-gui {
|
||||
position: relative !important;
|
||||
top: 0 !important;
|
||||
right: 0 !important;
|
||||
max-height: calc(100vh - 200px);
|
||||
overflow-y: auto;
|
||||
border-radius: 0 0 5px 5px;
|
||||
z-index: 2;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
#controls-wrapper .lil-gui * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* Override resize cursor when dragging */
|
||||
#controls-wrapper.dragging,
|
||||
#texture-panel-wrapper.dragging {
|
||||
cursor: grabbing !important;
|
||||
}
|
||||
|
||||
#controls-wrapper.dragging .lil-gui,
|
||||
#controls-wrapper.dragging .lil-gui * {
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
#texture-panel-wrapper.dragging * {
|
||||
cursor: grabbing !important;
|
||||
}
|
||||
|
||||
/* Floatable Texture Panel */
|
||||
#texture-panel-wrapper {
|
||||
resize: both;
|
||||
min-width: 300px;
|
||||
max-width: 600px;
|
||||
z-index: 150;
|
||||
}
|
||||
|
||||
#texture-panel-wrapper.minimized #texture-panel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#texture-panel-header:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* Texture panel styling */
|
||||
#texture-panel .texture-item {
|
||||
margin: 10px 0;
|
||||
@@ -316,9 +434,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="texture-panel" style="display: none; position: absolute; bottom: 10px; right: 10px; background: rgba(0, 0, 0, 0.8); color: white; padding: 15px; border-radius: 5px; font-size: 12px; max-width: 400px; max-height: 500px; overflow-y: auto;">
|
||||
<h3 style="margin: 0 0 10px 0; font-size: 14px; border-bottom: 1px solid #666; padding-bottom: 5px;">Textures</h3>
|
||||
<div id="texture-list"></div>
|
||||
<div id="texture-panel-wrapper" style="display: none; position: absolute; bottom: 10px; right: 10px;">
|
||||
<div id="texture-panel-header" style="background: linear-gradient(135deg, #4CAF50 0%, #388E3C 100%); color: white; padding: 8px 12px; cursor: move; user-select: none; display: flex; justify-content: space-between; align-items: center; font-size: 13px; font-weight: 500; border-radius: 5px 5px 0 0; border-bottom: 1px solid rgba(255, 255, 255, 0.1);">
|
||||
<div style="display: flex; align-items: center; gap: 8px;">
|
||||
<span>🖼️</span>
|
||||
<span>Textures</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 5px;">
|
||||
<button class="control-btn" id="texture-minimize-btn" style="background: rgba(255, 255, 255, 0.2); border: none; color: white; width: 24px; height: 24px; border-radius: 3px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 14px; transition: background 0.2s;">−</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="texture-panel" style="background: rgba(0, 0, 0, 0.85); color: white; padding: 15px; border-radius: 0 0 5px 5px; font-size: 12px; max-width: 400px; max-height: 500px; overflow-y: auto; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);">
|
||||
<div id="texture-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="loading-overlay">
|
||||
|
||||
@@ -1569,6 +1569,42 @@ function applyTextureToMaterial(material, paramName, texture, isEnabled = true)
|
||||
material.needsUpdate = true;
|
||||
}
|
||||
|
||||
// Map OpenPBR parameter names to Three.js texture map names
|
||||
function getMapNameForParameter(groupName, paramName) {
|
||||
const paramKey = `${groupName}_${paramName}`;
|
||||
const mapping = {
|
||||
'base_color': 'map',
|
||||
'specular_roughness': 'roughnessMap',
|
||||
'geometry_normal': 'normalMap',
|
||||
'coat_normal': 'clearcoatNormalMap',
|
||||
'emission_color': 'emissiveMap',
|
||||
'base_metalness': 'metalnessMap'
|
||||
};
|
||||
return mapping[paramKey] || null;
|
||||
}
|
||||
|
||||
// Get texture info for a material parameter (from userData.textures)
|
||||
function getTextureInfoForParameter(material, groupName, paramName) {
|
||||
if (!material || !material.threeMaterial || !material.threeMaterial.userData.textures) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const mapName = getMapNameForParameter(groupName, paramName);
|
||||
if (!mapName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const texInfo = material.threeMaterial.userData.textures[mapName];
|
||||
if (texInfo) {
|
||||
return {
|
||||
...texInfo,
|
||||
mapName: mapName
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get texture info for a material parameter
|
||||
function getTextureInfo(materialData, category, paramName) {
|
||||
if (!materialData || !materialData.hasOpenPBR || !materialData.openPBR) {
|
||||
@@ -3105,8 +3141,8 @@ function extractOpenPBRParams(materialData) {
|
||||
// It's wrapped - return the actual value
|
||||
return val.value;
|
||||
} else if (val.textureId !== undefined && val.value === undefined) {
|
||||
// It's a texture-only reference, skip for now (GUI doesn't handle texture editing yet)
|
||||
return null;
|
||||
// It's a texture-only reference, preserve the object so GUI can show it with texture info
|
||||
return val;
|
||||
}
|
||||
}
|
||||
// It's already a plain value
|
||||
@@ -3915,10 +3951,13 @@ function createParameterControls(material) {
|
||||
let rawValue = params[groupName][paramName];
|
||||
if (rawValue === undefined) return;
|
||||
|
||||
// Check if this parameter has a texture
|
||||
const hasTexture = rawValue && typeof rawValue === 'object' && rawValue.textureId !== undefined;
|
||||
|
||||
// Extract actual value if it's wrapped in an object with {name, type, value} structure
|
||||
const value = (rawValue && typeof rawValue === 'object' && rawValue.value !== undefined)
|
||||
? rawValue.value
|
||||
: rawValue;
|
||||
: (hasTexture ? [1, 1, 1] : rawValue); // Default color if texture-only
|
||||
|
||||
if (paramDef.type === 'color') {
|
||||
// Color picker
|
||||
@@ -3927,7 +3966,7 @@ function createParameterControls(material) {
|
||||
//color: [colorValue[0] * 255, colorValue[1] * 255, colorValue[2] * 255]
|
||||
color: [colorValue[0], colorValue[1], colorValue[2]]
|
||||
};
|
||||
groupFolder.addColor(colorObj, 'color').name(paramName).onChange(val => {
|
||||
const controller = groupFolder.addColor(colorObj, 'color').name(paramName).onChange(val => {
|
||||
const r = val[0]; // / 255;
|
||||
const g = val[1]; // / 255;
|
||||
const b = val[2]; // / 255;
|
||||
@@ -3935,6 +3974,21 @@ function createParameterControls(material) {
|
||||
params[groupName][paramName] = [r, g, b];
|
||||
updateMaterialFromParams(threeMat, params);
|
||||
});
|
||||
|
||||
// Add texture view button if this parameter has a texture
|
||||
if (hasTexture) {
|
||||
const textureInfo = getTextureInfoForParameter(material, groupName, paramName);
|
||||
if (textureInfo && textureInfo.texture) {
|
||||
const viewBtn = document.createElement('button');
|
||||
viewBtn.textContent = '🖼️';
|
||||
viewBtn.title = 'View texture';
|
||||
viewBtn.style.cssText = 'margin-left: 5px; padding: 2px 8px; background: #2196F3; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 14px;';
|
||||
viewBtn.onclick = () => {
|
||||
enlargeTexture(textureInfo.texture, formatTextureName(textureInfo.mapName || paramName));
|
||||
};
|
||||
controller.domElement.parentElement.appendChild(viewBtn);
|
||||
}
|
||||
}
|
||||
} else if (paramDef.type === 'boolean') {
|
||||
// Checkbox
|
||||
const boolObj = { [paramName]: !!value };
|
||||
@@ -3988,7 +4042,10 @@ function updateMaterialFromParams(material, params) {
|
||||
if (params.base) {
|
||||
if (params.base.color) {
|
||||
console.log("[base_color] ", params.base.color);
|
||||
const [r, g, b] = srgbToDisplayP3(...params.base.color);
|
||||
// Handle both array values and texture objects
|
||||
const colorValue = Array.isArray(params.base.color) ? params.base.color :
|
||||
(params.base.color.value || [1, 1, 1]);
|
||||
const [r, g, b] = srgbToDisplayP3(...colorValue);
|
||||
material.color.setRGB(r, g, b);
|
||||
}
|
||||
if (params.base.metalness !== undefined) {
|
||||
|
||||
Reference in New Issue
Block a user