Skip to content

Commit

Permalink
move code from selector to cull-mesh.js
Browse files Browse the repository at this point in the history
  • Loading branch information
memelotsqui committed Nov 23, 2023
1 parent deccb04 commit 0d379ed
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 49 deletions.
10 changes: 1 addition & 9 deletions src/components/Selector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"
import { MToonMaterial, VRMLoaderPlugin, VRMUtils } from "@pixiv/three-vrm"
import cancel from "../../public/ui/selector/cancel.png"
import { addModelData, disposeVRM } from "../library/utils"
import { computeBoundsTree, disposeBoundsTree, acceleratedRaycast, SAH } from 'three-mesh-bvh';
import {ViewContext} from "../context/ViewContext"
import tick from "../../public/ui/selector/tick.svg"
import { AudioContext } from "../context/AudioContext"
import { SceneContext } from "../context/SceneContext"
import { SoundContext } from "../context/SoundContext"
import {
renameVRMBones,
createFaceNormals,
createBoneDirection,
} from "../library/utils"
import { LipSync } from '../library/lipsync'
Expand All @@ -26,9 +24,7 @@ import MenuTitle from "./MenuTitle"
import { saveVRMCollidersToUserData } from "../library/load-utils"


THREE.BufferGeometry.prototype.computeBoundsTree = computeBoundsTree;
THREE.BufferGeometry.prototype.disposeBoundsTree = disposeBoundsTree;
THREE.Mesh.prototype.raycast = acceleratedRaycast;


export default function Selector({confirmDialog, uploadVRMURL, templateInfo, animationManager, blinkManager, lookatManager, effectManager}) {
const {
Expand Down Expand Up @@ -623,10 +619,6 @@ export default function Selector({confirmDialog, uploadVRMURL, templateInfo, ani
if (cullingIgnore.indexOf(child.name) === -1)
cullingMeshes.push(child)

// if (child.geometry.boundsTree == null)
// child.geometry.computeBoundsTree({strategy:SAH});

createFaceNormals(child.geometry)
if (child.isSkinnedMesh) {
createBoneDirection(child)
if (vrm.meta?.metaVersion === '0'){
Expand Down
53 changes: 33 additions & 20 deletions src/library/cull-mesh.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { Mesh, BufferAttribute, BackSide, FrontSide, Raycaster, Vector3, Color, BufferGeometry,LineBasicMaterial,Line, MeshBasicMaterial } from "three";
import { Mesh, Triangle, BufferAttribute, BackSide, FrontSide, Raycaster, Vector3, Color, BufferGeometry,LineBasicMaterial,Line, MeshBasicMaterial } from "three";
import { computeBoundsTree, disposeBoundsTree, acceleratedRaycast, SAH } from 'three-mesh-bvh';

let origin = new Vector3();
let direction = new Vector3();
let worldScale = new Vector3();
let worldPosition = new Vector3();
const intersections = [];

const raycaster = new Raycaster();
Expand All @@ -17,11 +15,37 @@ const backMat = new MeshBasicMaterial({side:BackSide})

let mainScene;

BufferGeometry.prototype.computeBoundsTree = computeBoundsTree;
BufferGeometry.prototype.disposeBoundsTree = disposeBoundsTree;
Mesh.prototype.raycast = acceleratedRaycast;

const createFaceNormals = (geometry) => {
const pos = geometry.attributes.position;
const idx = geometry.index;

const tri = new Triangle(); // for re-use
const a = new Vector3(), b = new Vector3(), c = new Vector3(); // for re-use

const faceNormals = [];

//set foreach vertex
for (let f = 0; f < (idx.array.length / 3); f++) {
const idxBase = f * 3;
a.fromBufferAttribute(pos, idx.getX(idxBase + 0));
b.fromBufferAttribute(pos, idx.getX(idxBase + 1));
c.fromBufferAttribute(pos, idx.getX(idxBase + 2));
tri.set(a, b, c);
faceNormals.push(tri.getNormal(new Vector3()));
}
geometry.userData.faceNormals = faceNormals;
}

const createCloneCullMesh = (mesh) => {
// clone mesh
const clonedGeometry = mesh.geometry.clone();
const clonedMaterial = mesh.material.clone();


// vrm0 mesh rotation
if (!mesh.userData.isVRM0){
const positions = clonedGeometry.attributes.position;
Expand All @@ -35,6 +59,7 @@ const createCloneCullMesh = (mesh) => {
const clonedMesh = new Mesh(clonedGeometry, clonedMaterial);

// bvh calculation
createFaceNormals(clonedMesh.geometry)
clonedMesh.geometry.computeBoundsTree({strategy:SAH});
return clonedMesh;
}
Expand Down Expand Up @@ -63,16 +88,6 @@ export const CullHiddenFaces = async(meshes) => {
meshData[mesh.userData.cullLayer] = {origMeshes:[], cloneMeshes:[], posMeshes:[], negMeshes:[], scaleMeshes:[], positionMeshes:[]}
}


// mesh.getWorldScale(worldScale);
// mesh.getWorldPosition(worldPosition);
worldScale.set(1,1,1)
worldPosition.set(0,0,0)
meshData[mesh.userData.cullLayer].scaleMeshes.push(worldScale);
meshData[mesh.userData.cullLayer].positionMeshes.push(worldPosition);



if (mesh.userData.cullingClone == null){
mesh.userData.cullingClone = createCloneCullMesh(mesh);
mesh.userData.cullingCloneP = mesh.userData.cullingClone.clone();
Expand Down Expand Up @@ -118,15 +133,13 @@ export const CullHiddenFaces = async(meshes) => {

const mesh = meshData[i].origMeshes[k];
const cloneMesh = meshData[i].cloneMeshes[k];
const meshScale = meshData[i].scaleMeshes[k];
const meshPosition = meshData[i].positionMeshes[k];
const index = mesh.userData.origIndexBuffer.array;
const vertexData = cloneMesh.geometry.attributes.position.array;
const normalsData = cloneMesh.geometry.attributes.normal.array;
const faceNormals = cloneMesh.geometry.userData.faceNormals;
geomsIndices.push({
geom: mesh.geometry,
index: getIndexBuffer(meshPosition,meshScale, index,vertexData,normalsData, faceNormals, hitArr,mesh.userData.cullDistance/*,i === 0*/)
index: getIndexBuffer(index,vertexData,normalsData, faceNormals, hitArr,mesh.userData.cullDistance/*,i === 0*/)
})
}
}
Expand Down Expand Up @@ -163,7 +176,7 @@ const getDistanceInOut = (distanceArr) => {
return [distIn, distOut]
}

const getIndexBuffer = (meshPosition, meshScale, index, vertexData, normalsData, faceNormals, intersectModels, distanceArr, debug = false) =>{
const getIndexBuffer = (index, vertexData, normalsData, faceNormals, intersectModels, distanceArr, debug = false) =>{

const indexCustomArr = [];
const distArr = getDistanceInOut(distanceArr);
Expand Down Expand Up @@ -195,9 +208,9 @@ const getIndexBuffer = (meshPosition, meshScale, index, vertexData, normalsData,

// move the origin away to have the raycast being casted from outside
origin.set(
(vertexData[vi] * meshScale.x ) + meshPosition.x,
(vertexData[vi+1] * meshScale.y ) + meshPosition.y,
(vertexData[vi+2] * meshScale.z) + meshPosition.z)
vertexData[vi],
vertexData[vi+1],
vertexData[vi+2])
.add(direction.clone().multiplyScalar(distIn))

//invert the direction of the raycaster as we moved it away from its origin
Expand Down
21 changes: 1 addition & 20 deletions src/library/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -429,26 +429,7 @@ export function disposeVRM(vrm) {

VRMUtils.deepDispose( model );
}
export const createFaceNormals = (geometry) => {
const pos = geometry.attributes.position;
const idx = geometry.index;

const tri = new THREE.Triangle(); // for re-use
const a = new THREE.Vector3(), b = new THREE.Vector3(), c = new THREE.Vector3(); // for re-use

const faceNormals = [];

//set foreach vertex
for (let f = 0; f < (idx.array.length / 3); f++) {
const idxBase = f * 3;
a.fromBufferAttribute(pos, idx.getX(idxBase + 0));
b.fromBufferAttribute(pos, idx.getX(idxBase + 1));
c.fromBufferAttribute(pos, idx.getX(idxBase + 2));
tri.set(a, b, c);
faceNormals.push(tri.getNormal(new THREE.Vector3()));
}
geometry.userData.faceNormals = faceNormals;
};

export const createBoneDirection = (skinMesh) => {
const geometry = skinMesh.geometry;

Expand Down

0 comments on commit 0d379ed

Please sign in to comment.