Armature mesh transformation proof of concept

This commit is contained in:
JannisX11 2025-03-30 23:21:29 +02:00
parent 3d4ba39d8e
commit f7706f2fb9
4 changed files with 90 additions and 15 deletions

View File

@ -306,6 +306,18 @@ export const Animator = {
})
})
for (let mesh of Mesh.all) {
let array = mesh.getParentArray();
let mesh_index = array.indexOf(mesh);
let rig_root = array[mesh_index+1];
if (rig_root instanceof ArmatureBone) {
animations.forEach(animation => {
let animator = animation.getBoneAnimator(rig_root);
animator.displayMeshDeform(mesh);
});
}
}
Animator.resetLastValues();
scene.updateMatrixWorld();

View File

@ -1,4 +1,5 @@
import Wintersky from 'wintersky';
import { THREE } from '../../lib/libs';
export class GeneralAnimator {
constructor(uuid, animation) {
@ -595,17 +596,6 @@ class ArmatureBoneAnimator extends BoneAnimator {
return (this.element && this.element && this.element.mesh);
}
displayPosition(arr, multiplier = 1) {
}
displayRotation(arr, multiplier = 1) {
let element = this.element;
let mesh = element.getParentArray().filter(m => m instanceof Mesh)[0];
if (!mesh) return;
for (let vkey of vertices) {}
var bone = this.element.mesh
if (arr) {
bone.position.x -= arr[0] * multiplier;
@ -614,19 +604,76 @@ class ArmatureBoneAnimator extends BoneAnimator {
}
return this;
}
displayRotation(arr, multiplier = 1) {
var mesh = this.element.mesh
if (arr) {
if (arr.length === 4) {
var added_rotation = new THREE.Euler().setFromQuaternion(new THREE.Quaternion().fromArray(arr), 'ZYX')
mesh.rotation.x -= added_rotation.x * multiplier
mesh.rotation.y -= added_rotation.y * multiplier
mesh.rotation.z += added_rotation.z * multiplier
} else {
arr.forEach((n, i) => {
mesh.rotation[getAxisLetter(i)] += Math.degToRad(n) * (i == 2 ? 1 : -1) * multiplier
})
}
}
return this;
}
displayMeshDeform(mesh) {
if (!mesh) return;
// Only gets called at the base bone of each rig
let matrices = {};
let bones = [];
let element = this.getElement();
let mesh_world_matrix_inverse = new THREE.Matrix4().copy(mesh.mesh.matrixWorld).invert();
let vertex_offsets = {};
let vector = new THREE.Vector3();
let vector2 = new THREE.Vector3();
element.parent.mesh.updateMatrixWorld();
element.forEachChild(bone => {
let matrix = new THREE.Matrix4().multiplyMatrices(bone.mesh.matrixWorld, mesh_world_matrix_inverse);
matrices[bone.uuid] = matrix;
bones.push(bone);
}, ArmatureBone, true);
for (let vkey in mesh.vertices) {
vector.fromArray(mesh.vertices[vkey]);
vector2.copy(vector2);
for (let bone of bones) {
let matrix = matrices[bone.uuid];
if (true) {
vector.applyMatrix4(matrix);
}
}
vector.sub(vector2);
//vector.lerpVectors();
vertex_offsets[vkey] = vector.toArray();
}
Mesh.preview_controller.updateGeometry(mesh, vertex_offsets);
}
displayFrame(multiplier = 1) {
if (!this.doRender()) return;
this.getElement()
if (!this.muted.position) {
this.displayPosition(this.interpolate('position'), multiplier);
this.displayRotation(this.interpolate('position'), multiplier);
}
if (!this.muted.rotation) {
this.displayRotation(this.interpolate('rotation'), multiplier);
}
this.displayMeshDeform();
}
}
ArmatureBoneAnimator.prototype.type = 'null_object';
ArmatureBoneAnimator.prototype.channels = {
position: {name: tl('timeline.position'), mutable: true, transform: true, max_data_points: 2},
rotation: {name: tl('timeline.rotation'), mutable: true, transform: true, max_data_points: 2},
}
ArmatureBone.animator = ArmatureBoneAnimator;

View File

@ -185,7 +185,7 @@ export class ArmatureBone extends OutlinerElement {
offset.z += this.parent.origin[2];
}
} else {
offset = Reusable.vec3.fromArray(this.position);
offset = Reusable.vec3.fromArray(this.origin);
}
offset.applyQuaternion(q);
pos.add(offset);
@ -287,6 +287,11 @@ export class ArmatureBone extends OutlinerElement {
i++;
}
}
static behavior = {
movable: true,
rotatable: true,
hide_in_screenshot: true,
}
}
ArmatureBone.prototype.title = tl('data.armature_bone');
ArmatureBone.prototype.type = 'armature_bone';
@ -313,6 +318,7 @@ OutlinerElement.registerType(ArmatureBone, 'armature_bone');
new Property(ArmatureBone, 'vector', 'origin', {default: [0, 0, 0]});
new Property(ArmatureBone, 'vector', 'rotation');
new Property(ArmatureBone, 'object', 'vertex_weights');
new NodePreviewController(ArmatureBone, {
setup(element) {
@ -320,7 +326,7 @@ new NodePreviewController(ArmatureBone, {
object_3d.rotation.order = 'ZYX';
object_3d.uuid = element.uuid.toUpperCase();
object_3d.name = element.name;
object_3d.isArmatureBone = true;
object_3d.isElement = true;
Project.nodes_3d[element.uuid] = object_3d;

View File

@ -1051,7 +1051,7 @@ new NodePreviewController(Mesh, {
this.dispatchEvent('setup', {element});
},
updateGeometry(element) {
updateGeometry(element, vertex_offsets) {
let {mesh} = element;
let point_position_array = [];
@ -1063,6 +1063,16 @@ new NodePreviewController(Mesh, {
mesh.outline.vertex_order.empty();
let {vertices, faces} = element;
if (vertex_offsets) {
vertices = {};
for (let vkey in element.vertices) {
vertices[vkey] = element.vertices[vkey].slice();
if (vertex_offsets[vkey] instanceof Array) {
vertices[vkey].V3_add(vertex_offsets[vkey])
}
}
}
for (let key in vertices) {
let vector = vertices[key];
point_position_array.push(...vector);