Allow blueprint reference images in front of the model

This commit is contained in:
JannisX11 2025-03-21 19:22:07 +01:00
parent d790320469
commit 03ab1fc2d1
5 changed files with 54 additions and 33 deletions

View File

@ -481,7 +481,8 @@ var codec = new Codec('project', {
let reference = new ReferenceImage({
position: [template.x, template.y + template.size/2],
size: [template.size/2, template.size/2],
layer: template.lock ? 'blueprint' : 'background',
layer: 'background',
is_blueprint: template.lock,
source: template.image,
name: (template.image && !template.image.startsWith('data:')) ? template.image.split([/[/\\]/]).last() : 'Reference'
}).addAsReference();

View File

@ -75,7 +75,7 @@ THREE.OrbitControls = function ( object, preview ) {
this.updateSceneScale = function() {
ReferenceImage.active.forEach(ref => {
if (ref.layer == 'blueprint' && ref.attached_side == scope.preview.angle) {
if (ref.is_blueprint && ref.attached_side == scope.preview.angle) {
ref.updateTransform()
}
})

View File

@ -1918,7 +1918,8 @@ export function initCanvas() {
position: [0, 0],
size: [528, 528],
attached_side: 'south',
layer: 'blueprint'
layer: 'background',
is_blueprint: true
}).addAsBuiltIn(),
canvas_scenes.inventory_full = new ReferenceImage({
@ -1928,7 +1929,8 @@ export function initCanvas() {
position: [0, -215.6],
size: [1390, 1310],
attached_side: 'south',
layer: 'blueprint'
layer: 'background',
is_blueprint: true
}).addAsBuiltIn(),
canvas_scenes.hud = new ReferenceImage({
@ -1938,7 +1940,8 @@ export function initCanvas() {
position: [-112, -70],
size: [1695, 308],
attached_side: 'south',
layer: 'blueprint'
layer: 'background',
is_blueprint: true
}).addAsBuiltIn(),
MediaPreview = new Preview({id: 'media', offscreen: true});

View File

@ -4,6 +4,7 @@ export class ReferenceImage {
this.name = '';
this.layer = '';
this.scope = '';
this.is_blueprint = false;
this.position = [0, 0];
this.size = [0, 0];
this.flip_x = false;
@ -99,6 +100,9 @@ export class ReferenceImage {
for (let key in ReferenceImage.properties) {
ReferenceImage.properties[key].merge(this, data)
}
if (data.is_blueprint) {
this.enableBlueprintMode();
}
}
getSaveCopy() {
let copy = {};
@ -116,14 +120,17 @@ export class ReferenceImage {
resolveCondition() {
if (!Condition(this.condition)) return false;
if (this.modes.length && !this.modes.includes(Modes.selected.id)) return false;
if (this.layer == 'blueprint') {
if (this.is_blueprint) {
return Preview.all.find(p => p.isOrtho && p.angle == this.attached_side) !== undefined;
}
return true;
}
addAsReference(save) {
Project.reference_images.push(this);
if (Preview.selected && Preview.selected.angle) this.changeLayer('blueprint');
if (Preview.selected && Preview.selected.angle) {
this.enableBlueprintMode();
this.changeLayer('background');
}
this.scope = 'project';
this.update();
if (save) this.save();
@ -131,7 +138,10 @@ export class ReferenceImage {
}
addAsGlobalReference(save) {
ReferenceImage.global.push(this);
if (Preview.selected && Preview.selected.angle) this.changeLayer('blueprint');
if (Preview.selected && Preview.selected.angle) {
this.enableBlueprintMode();
this.changeLayer('background');
}
this.scope = 'global';
this.update();
if (save) this.save();
@ -196,18 +206,11 @@ export class ReferenceImage {
this.node.setAttribute('reference_layer', this.layer);
switch (this.layer) {
case 'background': {
Interface.preview.querySelector('.clamped_reference_images').append(this.node);
break;
}
case 'background':
case 'viewport': {
Interface.preview.querySelector('.clamped_reference_images').append(this.node);
break;
}
case 'blueprint': {
Interface.preview.querySelector('.clamped_reference_images').append(this.node);
break;
}
case 'float': default: {
Interface.work_screen.append(this.node);
break;
@ -271,12 +274,12 @@ export class ReferenceImage {
return this;
}
getZoomLevel() {
let preview = this.layer == 'blueprint' && Preview.all.find(p => p.isOrtho && p.angle == this.attached_side);
let preview = this.is_blueprint && Preview.all.find(p => p.isOrtho && p.angle == this.attached_side);
return preview ? preview.camOrtho.zoom * 2 : 1;
}
updateTransform() {
if (!this.node.isConnected) return this;
let preview = this.layer == 'blueprint' && Preview.all.find(p => p.isOrtho && p.angle == this.attached_side);
let preview = this.is_blueprint && Preview.all.find(p => p.isOrtho && p.angle == this.attached_side);
if (preview && preview.node.isConnected) {
let zoom = this.getZoomLevel();;
@ -364,7 +367,7 @@ export class ReferenceImage {
this.size[1] = Math.max(original_size[1] + offset[1] * sign_y, max_size[1]);
this.position[1] = original_position[1] + offset[1] / 2, 0;
if (this.layer !== 'blueprint') {
if (!this.is_blueprint) {
this.position[0] = Math.clamp(this.position[0], 0, this.node.parentNode.clientWidth);
this.position[1] = Math.clamp(this.position[1], 0, this.node.parentNode.clientHeight);
}
@ -457,9 +460,6 @@ export class ReferenceImage {
viewport: 'reference_image.layer.viewport',
float: 'reference_image.layer.float',
}
if (Preview.selected.angle) {
layers.blueprint = 'reference_image.layer.blueprint';
}
let options = Object.keys(layers).map(key => {
return {
name: layers[key],
@ -526,7 +526,7 @@ export class ReferenceImage {
this.position[0] = original_position[0] + offset[0] / zoom;
this.position[1] = original_position[1] + offset[1] / zoom;
if (this.layer !== 'blueprint') {
if (!this.is_blueprint) {
this.position[0] = Math.clamp(this.position[0], 0, this.node.parentNode.clientWidth);
this.position[1] = Math.clamp(this.position[1], 0, this.node.parentNode.clientHeight);
}
@ -620,6 +620,7 @@ export class ReferenceImage {
changeLayer(layer) {
if (layer == this.layer) return;
if (this.is_blueprint) this.is_blueprint = false;
if (layer == 'float' || this.layer == 'float') {
let preview_offset = $(Interface.preview).offset();
let workscreen_offset = $(Interface.work_screen).offset();
@ -628,10 +629,6 @@ export class ReferenceImage {
this.position[0] += (preview_offset.left - workscreen_offset.left) * sign;
this.position[1] += (preview_offset.top - workscreen_offset.top) * sign;
}
if (layer == 'blueprint' && Preview.selected?.angle) {
this.attached_side = Preview.selected.angle;
this.position.V2_set(0, 0);
}
this.layer = layer;
return this;
}
@ -651,6 +648,14 @@ export class ReferenceImage {
}
return this;
}
enableBlueprintMode() {
if (Preview.selected?.angle) {
this.is_blueprint = true;
if (this.layer == 'float') this.changeLayer('viewport');
this.attached_side = Preview.selected.angle;
this.position.V2_set(0, 0);
}
}
propertiesDialog() {
new Dialog('reference_image_properties', {
title: 'data.reference_image',
@ -664,7 +669,6 @@ export class ReferenceImage {
background: 'reference_image.layer.background',
viewport: 'reference_image.layer.viewport',
float: 'reference_image.layer.float',
blueprint: Preview.selected.angle ? 'reference_image.layer.blueprint' : undefined,
}},
scope: {type: 'select', label: 'reference_image.scope', value: this.scope, options: {
project: 'reference_image.scope.project',
@ -676,6 +680,7 @@ export class ReferenceImage {
opacity: {type: 'range', label: 'reference_image.opacity', editable_range_label: true, value: this.opacity * 100, min: 0, max: 100, step: 1},
visibility: {type: 'checkbox', label: 'reference_image.visibility', value: this.visibility},
sync_to_timeline: {type: 'checkbox', label: 'reference_image.sync_to_timeline', value: this.sync_to_timeline, condition: this.is_video && Format.animation_mode},
is_blueprint: {type: 'checkbox', label: 'reference_image.blueprint', value: this.is_blueprint, condition: () => Preview.selected.angle},
clear_mode: {type: 'checkbox', label: 'reference_image.clear_mode', value: this.clear_mode},
},
onConfirm: (result) => {
@ -683,6 +688,7 @@ export class ReferenceImage {
let clear_mode_before = this.clear_mode;
this.extend({
source: result.source,
is_blueprint: result.is_blueprint,
position: result.position,
size: result.size,
rotation: result.rotation,
@ -742,11 +748,24 @@ ReferenceImage.prototype.menu = new Menu([
ref.update().save();
}
},
{
id: 'blueprint',
name: 'reference_image.blueprint',
icon: (ref) => ref.is_blueprint,
click(ref) {
if (ref.is_blueprint) {
ref.is_blueprint = false;
} else {
ref.enableBlueprintMode();
}
ref.update().save();
}
},
{
id: 'clear_mode',
name: 'reference_image.clear_mode',
icon: (ref) => ref.clear_mode,
//condition: ref => ref.layer == 'blueprint',
//condition: ref => ref.is_blueprint,
click(ref) {
ref.clear_mode = !ref.clear_mode;
ref.updateClearMode();
@ -768,9 +787,6 @@ ReferenceImage.prototype.menu = new Menu([
viewport: 'reference_image.layer.viewport',
float: 'reference_image.layer.float',
}
if (Preview.selected.angle) {
layers.blueprint = 'reference_image.layer.blueprint';
}
let children = [];
for (let key in layers) {
children.push({
@ -839,6 +855,7 @@ ReferenceImage.prototype.menu = new Menu([
new Property(ReferenceImage, 'string', 'name', {default: 'Reference'});
new Property(ReferenceImage, 'string', 'layer', {default: 'background'});
new Property(ReferenceImage, 'string', 'scope', {default: 'global'});
new Property(ReferenceImage, 'boolean', 'is_blueprint');
new Property(ReferenceImage, 'vector2', 'position');
new Property(ReferenceImage, 'vector2', 'size', {default: [400, 300]});
new Property(ReferenceImage, 'boolean', 'flip_x');

View File

@ -2318,7 +2318,7 @@
"reference_image.layer.background": "Behind Model",
"reference_image.layer.viewport": "Above Model",
"reference_image.layer.float": "Above Interface",
"reference_image.layer.blueprint": "Locked Blueprint",
"reference_image.blueprint": "Locked Blueprint",
"reference_image.scope": "Scope",
"reference_image.scope.project": "Just this project",
"reference_image.scope.global": "All projects",