mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-22 23:24:10 +02:00
wip
This commit is contained in:
@@ -32,7 +32,7 @@ import { reactive, ref, shallowRef, triggerRef, watch } from 'vue';
|
|||||||
import { genId } from '../id.js';
|
import { genId } from '../id.js';
|
||||||
import { deepClone } from '../clone.js';
|
import { deepClone } from '../clone.js';
|
||||||
import { getObjectDef } from './object-defs.js';
|
import { getObjectDef } from './object-defs.js';
|
||||||
import { HorizontalCameraKeyboardMoveInput, findMaterial } from './utility.js';
|
import { HorizontalCameraKeyboardMoveInput, applyMorphTargetsToMesh, findMaterial } from './utility.js';
|
||||||
import * as sound from '@/utility/sound.js';
|
import * as sound from '@/utility/sound.js';
|
||||||
|
|
||||||
// babylonのドメイン知識は持たない
|
// babylonのドメイン知識は持たない
|
||||||
@@ -199,7 +199,7 @@ class ModelManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const toMerge = [] as BABYLON.Mesh[];
|
const _toMerge = [] as BABYLON.Mesh[];
|
||||||
for (const mesh of childMeshes) {
|
for (const mesh of childMeshes) {
|
||||||
let fixedMesh = mesh;
|
let fixedMesh = mesh;
|
||||||
|
|
||||||
@@ -223,7 +223,15 @@ class ModelManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fixedMesh.isVisible = false;
|
fixedMesh.isVisible = false;
|
||||||
toMerge.push(fixedMesh);
|
_toMerge.push(fixedMesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
const toMerge = [] as BABYLON.Mesh[];
|
||||||
|
for (const mesh of _toMerge) {
|
||||||
|
const newMesh = mesh.clone(mesh.name + '_bakeMerged');
|
||||||
|
applyMorphTargetsToMesh(newMesh);
|
||||||
|
//newMesh.bakeCurrentTransformIntoVertices();
|
||||||
|
toMerge.push(newMesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
const merged = BABYLON.Mesh.MergeMeshes(toMerge, false, true, undefined, false, true);
|
const merged = BABYLON.Mesh.MergeMeshes(toMerge, false, true, undefined, false, true);
|
||||||
|
|||||||
@@ -491,39 +491,55 @@ export function findMaterial(rootMesh: BABYLON.AbstractMesh, keyword: string): B
|
|||||||
throw new Error(`Material with keyword "${keyword}" not found`);
|
throw new Error(`Material with keyword "${keyword}" not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// merge all child meshes into the root mesh
|
export function applyMorphTargetsToMesh(mesh: BABYLON.Mesh) {
|
||||||
export function bakeMesh(rootMesh: BABYLON.Mesh) {
|
if (!mesh.morphTargetManager) {
|
||||||
const childMeshes = rootMesh.getChildMeshes();
|
return;
|
||||||
|
|
||||||
const toMerge = [] as BABYLON.Mesh[];
|
|
||||||
for (const mesh of childMeshes) {
|
|
||||||
let fixedMesh = mesh;
|
|
||||||
|
|
||||||
if (mesh instanceof BABYLON.InstancedMesh) {
|
|
||||||
const sourceMesh = mesh.sourceMesh;
|
|
||||||
const newMesh = sourceMesh.clone(mesh.name + '_baked');
|
|
||||||
|
|
||||||
newMesh.position = mesh.position.clone();
|
|
||||||
if (mesh.rotationQuaternion) {
|
|
||||||
newMesh.rotationQuaternion = mesh.rotationQuaternion.clone();
|
|
||||||
} else {
|
|
||||||
newMesh.rotation = mesh.rotation.clone();
|
|
||||||
}
|
|
||||||
newMesh.scaling = mesh.scaling.clone();
|
|
||||||
|
|
||||||
newMesh.parent = mesh.parent;
|
|
||||||
|
|
||||||
mesh.dispose();
|
|
||||||
|
|
||||||
fixedMesh = newMesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
toMerge.push(fixedMesh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const merged = BABYLON.Mesh.MergeMeshes(toMerge, true, true, undefined, false, true);
|
const morphTargetManager = mesh.morphTargetManager;
|
||||||
|
const positions = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
|
||||||
|
|
||||||
merged.setParent(rootMesh);
|
if (!positions) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return merged;
|
// Create a copy of the original positions to work with
|
||||||
|
const finalPositions = positions.slice();
|
||||||
|
|
||||||
|
// Apply each morph target
|
||||||
|
for (let targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
|
||||||
|
const target = morphTargetManager.getTarget(targetIndex);
|
||||||
|
const influence = target.influence;
|
||||||
|
|
||||||
|
if (influence === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the morph target positions
|
||||||
|
const targetPositions = target.getPositions();
|
||||||
|
|
||||||
|
if (!targetPositions || targetPositions.length !== positions.length) {
|
||||||
|
console.warn(`Morph target ${targetIndex} has invalid position data`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the morph target influence to each vertex
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
finalPositions[i] += (targetPositions[i] - positions[i]) * influence;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the mesh with the morphed positions
|
||||||
|
mesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, finalPositions);
|
||||||
|
|
||||||
|
// Update normals if available
|
||||||
|
const normals = mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
|
||||||
|
if (normals) {
|
||||||
|
// For simplicity, we'll just recompute the normals
|
||||||
|
mesh.createNormals(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh the mesh
|
||||||
|
mesh.refreshBoundingInfo();
|
||||||
|
mesh.computeWorldMatrix(true);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user