blockbench/js/outliner/locator.js

208 lines
5.6 KiB
JavaScript
Raw Normal View History

2019-07-18 00:02:07 +08:00
class Locator extends OutlinerElement {
2019-07-18 00:02:07 +08:00
constructor(data, uuid) {
super(data, uuid);
2020-07-16 15:32:59 +08:00
for (var key in Locator.properties) {
Locator.properties[key].reset(this);
}
2019-07-18 00:02:07 +08:00
if (data) {
this.extend(data);
}
}
2021-05-28 19:19:09 +08:00
get origin() {
return this.position;
2021-05-28 19:19:09 +08:00
}
2019-07-18 00:02:07 +08:00
extend(object) {
if (object.from) this.position.V3_set(object.from);
2020-07-16 15:32:59 +08:00
for (var key in Locator.properties) {
Locator.properties[key].merge(this, object)
}
2019-12-16 03:04:31 +08:00
this.sanitizeName();
Merge.boolean(this, object, 'export');
2019-07-18 00:02:07 +08:00
return this;
}
getUndoCopy() {
var copy = new Locator(this)
copy.uuid = this.uuid
2019-07-26 19:33:29 +08:00
copy.type = this.type;
2019-07-18 00:02:07 +08:00
delete copy.parent;
return copy;
}
getSaveCopy() {
2020-09-23 01:17:28 +08:00
let save = {};
2020-07-16 15:32:59 +08:00
for (var key in Locator.properties) {
2020-09-23 01:17:28 +08:00
Locator.properties[key].copy(this, save)
2020-07-16 15:32:59 +08:00
}
2020-09-23 01:17:28 +08:00
save.export = this.export ? undefined : false;
save.uuid = this.uuid;
save.type = 'locator';
return save;
2019-07-18 00:02:07 +08:00
}
init() {
if (this.parent instanceof Group == false) {
this.addTo(Group.selected)
}
super.init();
return this;
}
2019-12-16 03:04:31 +08:00
flip(axis, center) {
var offset = this.position[axis] - center
this.position[axis] = center - offset;
2021-05-28 19:19:09 +08:00
this.rotation.forEach((n, i) => {
if (i != axis) this.rotation[i] = -n;
})
2020-10-18 03:51:17 +08:00
// Name
flipNameOnAxis(this, axis);
2020-10-18 03:51:17 +08:00
this.createUniqueName();
this.preview_controller.updateTransform(this);
2019-12-16 03:04:31 +08:00
return this;
}
2019-09-04 15:37:38 +08:00
getWorldCenter() {
var pos = Reusable.vec1.set(0, 0, 0);
var q = Reusable.quat1.set(0, 0, 0, 1);
2019-12-16 03:04:31 +08:00
if (this.parent instanceof Group) {
THREE.fastWorldPosition(this.parent.mesh, pos);
2019-12-16 03:04:31 +08:00
this.parent.mesh.getWorldQuaternion(q);
var offset2 = Reusable.vec2.fromArray(this.parent.origin).applyQuaternion(q);
2019-12-16 03:04:31 +08:00
pos.sub(offset2);
}
var offset = Reusable.vec3.fromArray(this.position).applyQuaternion(q);
2019-12-16 03:04:31 +08:00
pos.add(offset);
2019-09-04 15:37:38 +08:00
return pos;
}
2019-07-18 00:02:07 +08:00
}
2019-12-16 03:04:31 +08:00
Locator.prototype.title = tl('data.locator');
Locator.prototype.type = 'locator';
Locator.prototype.icon = 'fa fa-anchor';
2020-04-26 02:25:07 +08:00
Locator.prototype.name_regex = 'a-z0-9_'
2019-12-16 03:04:31 +08:00
Locator.prototype.movable = true;
2021-05-28 19:19:09 +08:00
Locator.prototype.rotatable = true;
2019-12-16 03:04:31 +08:00
Locator.prototype.visibility = true;
Locator.prototype.buttons = [
2020-12-30 02:50:02 +08:00
Outliner.buttons.export,
2020-04-26 02:25:07 +08:00
Outliner.buttons.locked,
Outliner.buttons.visibility,
2019-12-16 03:04:31 +08:00
];
Locator.prototype.needsUniqueName = true;
Locator.prototype.menu = new Menu([
2023-06-21 00:31:29 +08:00
...Outliner.control_menu_group,
new MenuSeparator('settings'),
2021-08-08 01:46:54 +08:00
{
id: 'ignore_inherited_scale',
name: 'menu.locator.ignore_inherited_scale',
icon: locator => locator.ignore_inherited_scale ? 'check_box' : 'check_box_outline_blank',
click(clicked_locator) {
let value = !clicked_locator.ignore_inherited_scale;
let affected = Locator.selected.filter(locator => locator.ignore_inherited_scale != value);
Undo.initEdit({elements: affected});
affected.forEach(locator => {
locator.ignore_inherited_scale = value;
})
Undo.finishEdit('Change locator ignore inherit scale option');
}
},
2023-06-21 00:31:29 +08:00
new MenuSeparator('manage'),
2019-12-16 03:04:31 +08:00
'rename',
2023-06-21 00:31:29 +08:00
'toggle_visibility',
2019-12-16 03:04:31 +08:00
'delete'
])
2020-07-16 15:32:59 +08:00
new Property(Locator, 'string', 'name', {default: 'locator'})
new Property(Locator, 'vector', 'position')
new Property(Locator, 'vector', 'rotation')
2021-08-19 22:01:50 +08:00
new Property(Locator, 'boolean', 'ignore_inherited_scale')
new Property(Locator, 'boolean', 'visibility', {default: true});
new Property(Locator, 'boolean', 'locked');
OutlinerElement.registerType(Locator, 'locator');
(function() {
const map = new THREE.TextureLoader().load( 'assets/locator.png' );
map.magFilter = map.minFilter = THREE.NearestFilter;
new NodePreviewController(Locator, {
setup(element) {
let mesh = new THREE.Object3D();
Project.nodes_3d[element.uuid] = mesh;
mesh.name = element.uuid;
mesh.type = element.type;
mesh.isElement = true;
mesh.visible = element.visibility;
mesh.rotation.order = 'ZYX';
let material = new THREE.SpriteMaterial({
map,
alphaTest: 0.1,
sizeAttenuation: false
});
let sprite = new THREE.Sprite(material);
sprite.name = element.uuid;
sprite.type = element.type;
sprite.isElement = true;
mesh.add(sprite);
mesh.sprite = sprite;
this.updateTransform(element);
this.dispatchEvent('setup', {element});
},
updateTransform(element) {
NodePreviewController.prototype.updateTransform.call(this, element);
this.updateWindowSize(element);
},
updateSelection(element) {
let {mesh} = element;
mesh.sprite.material.color.set(element.selected ? gizmo_colors.outline : CustomTheme.data.colors.text);
mesh.sprite.material.depthTest = !element.selected;
mesh.renderOrder = element.selected ? 100 : 0;
this.dispatchEvent('update_selection', {element});
},
updateWindowSize(element) {
let size = 0.4 * Preview.selected.camera.fov / Preview.selected.height;
element.mesh.sprite.scale.set(size, size, size);
}
})
let locator_suggestion_list = $('<datalist id="locator_suggestion_list" hidden></datalist>').get(0);
document.body.append(locator_suggestion_list);
Locator.updateAutocompleteList = function() {
locator_suggestion_list.innerHTML = '';
Locator.all.forEach(locator => {
let option = document.createElement('option');
option.value = locator.name;
locator_suggestion_list.append(option);
})
}
})()
2019-07-18 00:02:07 +08:00
BARS.defineActions(function() {
2019-08-18 00:26:14 +08:00
new Action('add_locator', {
2019-07-18 00:02:07 +08:00
icon: 'fa-anchor',
category: 'edit',
condition: () => {return Format.locators && Modes.edit},
click: function () {
2019-09-06 06:16:54 +08:00
var objs = []
Undo.initEdit({elements: objs, outliner: true});
2019-12-16 03:04:31 +08:00
var locator = new Locator().addTo(Group.selected||selected[0]).init();
locator.select().createUniqueName();
objs.push(locator);
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Add locator');
Vue.nextTick(function() {
if (settings.create_rename.value) {
locator.rename();
}
})
2019-07-18 00:02:07 +08:00
}
})
})