mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-10 07:57:27 +02:00
Merge pull request #14745 from sabrina-shanman/material-inspector
(case 20748) Add material inspector to Luci.js
This commit is contained in:
commit
1584311689
4 changed files with 257 additions and 10 deletions
|
@ -14,7 +14,6 @@ import QtQuick.Layouts 1.3
|
|||
import stylesUit 1.0
|
||||
import controlsUit 1.0 as HifiControls
|
||||
import "configSlider"
|
||||
import "../lib/jet/qml" as Jet
|
||||
|
||||
Rectangle {
|
||||
HifiConstants { id: hifi;}
|
||||
|
@ -249,12 +248,6 @@ Rectangle {
|
|||
checked: render.mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"]
|
||||
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 {
|
||||
|
@ -277,6 +270,12 @@ Rectangle {
|
|||
checked: render.mainViewTask.getConfig("DrawZones")["enabled"]
|
||||
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 {}
|
||||
|
@ -303,5 +302,13 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
Row {
|
||||
HifiControls.Button {
|
||||
text: "Material"
|
||||
onClicked: {
|
||||
sendToScript({method: "openMaterialInspectorView"});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
(function() {
|
||||
var AppUi = Script.require('appUi');
|
||||
|
||||
var MaterialInspector = Script.require('./materialInspector.js');
|
||||
|
||||
var moveDebugCursor = false;
|
||||
var onMousePressEvent = function (e) {
|
||||
|
@ -41,11 +43,12 @@
|
|||
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.qml = qmlurl;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.handleWindowFunc = handleWindowFunc;
|
||||
|
||||
this.window;
|
||||
|
||||
|
@ -73,8 +76,10 @@
|
|||
presentationMode: Desktop.PresentationMode.NATIVE,
|
||||
size: {x: this.width, y: this.height}
|
||||
});
|
||||
this.handleWindowFunc(this.window);
|
||||
this.window.closed.connect(function () {
|
||||
that.killView();
|
||||
this.handleWindowFunc(undefined);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -84,8 +89,12 @@
|
|||
this._pages = {};
|
||||
};
|
||||
|
||||
Pages.prototype.addPage = function (command, title, qmlurl, width, height) {
|
||||
this._pages[command] = new Page(title, qmlurl, width, height);
|
||||
Pages.prototype.addPage = function (command, title, qmlurl, width, height, handleWindowFunc) {
|
||||
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) {
|
||||
|
@ -110,6 +119,7 @@
|
|||
pages.addPage('openEngineView', 'Render Engine', 'engineInspector.qml', 300, 400);
|
||||
pages.addPage('openEngineLODView', 'Render LOD', 'lod.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) {
|
||||
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