mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 01:57:43 +02:00
Add material inspector to Luci.js
This commit is contained in:
parent
a115af6353
commit
556a2ec3b6
4 changed files with 257 additions and 10 deletions
|
@ -14,7 +14,6 @@ import QtQuick.Layouts 1.3
|
||||||
import stylesUit 1.0
|
import stylesUit 1.0
|
||||||
import controlsUit 1.0 as HifiControls
|
import controlsUit 1.0 as HifiControls
|
||||||
import "configSlider"
|
import "configSlider"
|
||||||
import "../lib/jet/qml" as Jet
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
HifiConstants { id: hifi;}
|
HifiConstants { id: hifi;}
|
||||||
|
@ -249,12 +248,6 @@ Rectangle {
|
||||||
checked: render.mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"]
|
checked: render.mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"]
|
||||||
onCheckedChanged: { render.mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"] = checked }
|
onCheckedChanged: { render.mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"] = checked }
|
||||||
}
|
}
|
||||||
HifiControls.CheckBox {
|
|
||||||
boxSize: 20
|
|
||||||
text: "Transparents in HUD"
|
|
||||||
checked: render.mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"]
|
|
||||||
onCheckedChanged: { render.mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"] = checked }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Column {
|
Column {
|
||||||
|
@ -277,6 +270,12 @@ Rectangle {
|
||||||
checked: render.mainViewTask.getConfig("DrawZones")["enabled"]
|
checked: render.mainViewTask.getConfig("DrawZones")["enabled"]
|
||||||
onCheckedChanged: { render.mainViewTask.getConfig("ZoneRenderer")["enabled"] = checked; render.mainViewTask.getConfig("DrawZones")["enabled"] = checked; }
|
onCheckedChanged: { render.mainViewTask.getConfig("ZoneRenderer")["enabled"] = checked; render.mainViewTask.getConfig("DrawZones")["enabled"] = checked; }
|
||||||
}
|
}
|
||||||
|
HifiControls.CheckBox {
|
||||||
|
boxSize: 20
|
||||||
|
text: "Transparents in HUD"
|
||||||
|
checked: render.mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"]
|
||||||
|
onCheckedChanged: { render.mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"] = checked }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Separator {}
|
Separator {}
|
||||||
|
@ -303,5 +302,13 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Row {
|
||||||
|
HifiControls.Button {
|
||||||
|
text: "Material"
|
||||||
|
onClicked: {
|
||||||
|
sendToScript({method: "openMaterialInspectorView"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var AppUi = Script.require('appUi');
|
var AppUi = Script.require('appUi');
|
||||||
|
|
||||||
|
var MaterialInspector = Script.require('./materialInspector.js');
|
||||||
|
|
||||||
var moveDebugCursor = false;
|
var moveDebugCursor = false;
|
||||||
var onMousePressEvent = function (e) {
|
var onMousePressEvent = function (e) {
|
||||||
|
@ -41,11 +43,12 @@
|
||||||
Render.getConfig("RenderMainView").getConfig("DebugDeferredBuffer").size = { x: nx, y: ny, z: 1.0, w: 1.0 };
|
Render.getConfig("RenderMainView").getConfig("DebugDeferredBuffer").size = { x: nx, y: ny, z: 1.0, w: 1.0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
function Page(title, qmlurl, width, height) {
|
function Page(title, qmlurl, width, height, handleWindowFunc) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.qml = qmlurl;
|
this.qml = qmlurl;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
this.handleWindowFunc = handleWindowFunc;
|
||||||
|
|
||||||
this.window;
|
this.window;
|
||||||
|
|
||||||
|
@ -73,8 +76,10 @@
|
||||||
presentationMode: Desktop.PresentationMode.NATIVE,
|
presentationMode: Desktop.PresentationMode.NATIVE,
|
||||||
size: {x: this.width, y: this.height}
|
size: {x: this.width, y: this.height}
|
||||||
});
|
});
|
||||||
|
this.handleWindowFunc(this.window);
|
||||||
this.window.closed.connect(function () {
|
this.window.closed.connect(function () {
|
||||||
that.killView();
|
that.killView();
|
||||||
|
this.handleWindowFunc(undefined);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -84,8 +89,12 @@
|
||||||
this._pages = {};
|
this._pages = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
Pages.prototype.addPage = function (command, title, qmlurl, width, height) {
|
Pages.prototype.addPage = function (command, title, qmlurl, width, height, handleWindowFunc) {
|
||||||
this._pages[command] = new Page(title, qmlurl, width, height);
|
if (handleWindowFunc === undefined) {
|
||||||
|
// Workaround for bad linter
|
||||||
|
handleWindowFunc = function(window){};
|
||||||
|
}
|
||||||
|
this._pages[command] = new Page(title, qmlurl, width, height, handleWindowFunc);
|
||||||
};
|
};
|
||||||
|
|
||||||
Pages.prototype.open = function (command) {
|
Pages.prototype.open = function (command) {
|
||||||
|
@ -110,6 +119,7 @@
|
||||||
pages.addPage('openEngineView', 'Render Engine', 'engineInspector.qml', 300, 400);
|
pages.addPage('openEngineView', 'Render Engine', 'engineInspector.qml', 300, 400);
|
||||||
pages.addPage('openEngineLODView', 'Render LOD', 'lod.qml', 300, 400);
|
pages.addPage('openEngineLODView', 'Render LOD', 'lod.qml', 300, 400);
|
||||||
pages.addPage('openCullInspectorView', 'Cull Inspector', 'culling.qml', 300, 400);
|
pages.addPage('openCullInspectorView', 'Cull Inspector', 'culling.qml', 300, 400);
|
||||||
|
pages.addPage('openMaterialInspectorView', 'Material Inspector', 'materialInspector.qml', 300, 400, MaterialInspector.setWindow);
|
||||||
|
|
||||||
function fromQml(message) {
|
function fromQml(message) {
|
||||||
if (pages.open(message.method)) {
|
if (pages.open(message.method)) {
|
||||||
|
|
165
scripts/developer/utilities/render/materialInspector.js
Normal file
165
scripts/developer/utilities/render/materialInspector.js
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
//
|
||||||
|
// materialInspector.js
|
||||||
|
//
|
||||||
|
// Created by Sabrina Shanman on 2019-01-17
|
||||||
|
// Copyright 2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var activeWindow;
|
||||||
|
|
||||||
|
// Adapted from Samuel G's material painting script
|
||||||
|
function getTopMaterial(multiMaterial) {
|
||||||
|
// For non-models: multiMaterial[0] will be the top material
|
||||||
|
// For models, multiMaterial[0] is the base material, and multiMaterial[1] is the highest priority applied material
|
||||||
|
if (multiMaterial.length > 1) {
|
||||||
|
if (multiMaterial[1].priority > multiMaterial[0].priority) {
|
||||||
|
return multiMaterial[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return multiMaterial[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMaterial(type, id, meshPart) {
|
||||||
|
var mesh = Graphics.getModel(id);
|
||||||
|
var meshPartString = meshPart.toString();
|
||||||
|
if (!mesh) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var materials = mesh.materialLayers;
|
||||||
|
if (!materials[meshPartString] || materials[meshPartString].length <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var topMaterial = getTopMaterial(materials[meshPartString]);
|
||||||
|
var materialJSONText = JSON.stringify({
|
||||||
|
materialVersion: 1,
|
||||||
|
materials: topMaterial.material
|
||||||
|
}, null, 2);
|
||||||
|
|
||||||
|
toQml({method: "setObjectInfo", params: {id: id, type: type, meshPart: meshPart}});
|
||||||
|
toQml({method: "setMaterialJSON", params: {materialJSONText: materialJSONText}});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adapted from Samuel G's material painting script
|
||||||
|
function getHoveredMaterialLocation(event) {
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
|
var closest;
|
||||||
|
var id;
|
||||||
|
var type = "Entity";
|
||||||
|
var avatar = AvatarManager.findRayIntersection(pickRay);
|
||||||
|
var entity = Entities.findRayIntersection(pickRay, true);
|
||||||
|
var overlay = Overlays.findRayIntersection(pickRay, true);
|
||||||
|
|
||||||
|
closest = entity;
|
||||||
|
id = entity.entityID;
|
||||||
|
|
||||||
|
if (avatar.intersects && avatar.distance < closest.distance) {
|
||||||
|
closest = avatar;
|
||||||
|
id = avatar.avatarID;
|
||||||
|
type = "Avatar";
|
||||||
|
} else if (overlay.intersects && overlay.distance < closest.distance) {
|
||||||
|
closest = overlay;
|
||||||
|
id = overlay.overlayID;
|
||||||
|
type = "Overlay";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closest.intersects) {
|
||||||
|
return {
|
||||||
|
type: type,
|
||||||
|
id: id,
|
||||||
|
meshPart: (closest.extraInfo.shapeID ? closest.extraInfo.shapeID : 0)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pressedID;
|
||||||
|
var pressedMeshPart;
|
||||||
|
|
||||||
|
function mousePressEvent(event) {
|
||||||
|
if (!event.isLeftButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = getHoveredMaterialLocation(event);
|
||||||
|
|
||||||
|
if (result !== undefined) {
|
||||||
|
pressedID = result.id;
|
||||||
|
pressedMeshPart = result.meshPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseReleaseEvent(event) {
|
||||||
|
if (!event.isLeftButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = getHoveredMaterialLocation(event);
|
||||||
|
|
||||||
|
if (result !== undefined && result.id === pressedID && result.meshPart === pressedMeshPart) {
|
||||||
|
updateMaterial(result.type, result.id, result.meshPart);
|
||||||
|
setSelectedObject(result.id, result.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function killWindow() {
|
||||||
|
setWindow(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toQml(message) {
|
||||||
|
if (activeWindow === undefined) {
|
||||||
|
return; // Shouldn't happen
|
||||||
|
}
|
||||||
|
|
||||||
|
activeWindow.sendToQml(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fromQml(message) {
|
||||||
|
// No cases currently
|
||||||
|
}
|
||||||
|
|
||||||
|
var SELECT_LIST = "luci_materialInspector_SelectionList";
|
||||||
|
Selection.enableListHighlight(SELECT_LIST, {
|
||||||
|
outlineUnoccludedColor: { red: 255, green: 255, blue: 255 }
|
||||||
|
});
|
||||||
|
function setSelectedObject(id, type) {
|
||||||
|
Selection.clearSelectedItemsList(SELECT_LIST);
|
||||||
|
if (id !== undefined && !Uuid.isNull(id)) {
|
||||||
|
Selection.addToSelectedItemsList(SELECT_LIST, type.toLowerCase(), id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWindow(window) {
|
||||||
|
if (activeWindow !== undefined) {
|
||||||
|
setSelectedObject(Uuid.NULL, "");
|
||||||
|
activeWindow.closed.disconnect(killWindow);
|
||||||
|
activeWindow.fromQml.disconnect(fromQml);
|
||||||
|
Controller.mousePressEvent.disconnect(mousePressEvent);
|
||||||
|
Controller.mouseReleaseEvent.disconnect(mouseReleaseEvent);
|
||||||
|
activeWindow.close();
|
||||||
|
}
|
||||||
|
if (window !== undefined) {
|
||||||
|
window.closed.connect(killWindow);
|
||||||
|
window.fromQml.connect(fromQml);
|
||||||
|
Controller.mousePressEvent.connect(mousePressEvent);
|
||||||
|
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||||
|
}
|
||||||
|
activeWindow = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
setWindow(undefined);
|
||||||
|
Selection.disableListHighlight(SELECT_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(cleanup);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
setWindow: setWindow
|
||||||
|
};
|
65
scripts/developer/utilities/render/materialInspector.qml
Normal file
65
scripts/developer/utilities/render/materialInspector.qml
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
//
|
||||||
|
// materialInspector.qml
|
||||||
|
//
|
||||||
|
// Created by Sabrina Shanman on 2019-01-16
|
||||||
|
// Copyright 2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Controls 2.3 as Original
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
|
||||||
|
import stylesUit 1.0
|
||||||
|
import controlsUit 1.0 as HifiControls
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
HifiConstants { id: hifi;}
|
||||||
|
color: Qt.rgba(hifi.colors.baseGray.r, hifi.colors.baseGray.g, hifi.colors.baseGray.b, 0.8);
|
||||||
|
id: root;
|
||||||
|
|
||||||
|
function fromScript(message) {
|
||||||
|
switch (message.method) {
|
||||||
|
case "setObjectInfo":
|
||||||
|
entityIDInfo.text = "Type: " + message.params.type + "\nID: " + message.params.id + "\nMesh Part: " + message.params.meshPart;
|
||||||
|
break;
|
||||||
|
case "setMaterialJSON":
|
||||||
|
materialJSONText.text = message.params.materialJSONText;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: entityIDContainer
|
||||||
|
height: 52
|
||||||
|
width: root.width
|
||||||
|
color: Qt.rgba(root.color.r * 0.7, root.color.g * 0.7, root.color.b * 0.7, 0.8);
|
||||||
|
TextEdit {
|
||||||
|
id: entityIDInfo
|
||||||
|
text: "Type: Unknown\nID: None\nMesh Part: Unknown"
|
||||||
|
font.pointSize: 9
|
||||||
|
color: "#FFFFFF"
|
||||||
|
readOnly: true
|
||||||
|
selectByMouse: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Original.ScrollView {
|
||||||
|
anchors.top: entityIDContainer.bottom
|
||||||
|
height: root.height - entityIDContainer.height
|
||||||
|
width: root.width
|
||||||
|
clip: true
|
||||||
|
Original.ScrollBar.horizontal.policy: Original.ScrollBar.AlwaysOff
|
||||||
|
TextEdit {
|
||||||
|
id: materialJSONText
|
||||||
|
text: "Click an object to get material JSON"
|
||||||
|
width: root.width
|
||||||
|
font.pointSize: 10
|
||||||
|
color: "#FFFFFF"
|
||||||
|
readOnly: true
|
||||||
|
selectByMouse: true
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue