#javascript #reactjs #three.js #3d
Вопрос:
Здравствуйте, я хочу центрировать свой 3d-объект в центре сцены, и я также хочу иметь возможность вырезать некоторые сетки, а затем центрировать вырезанные сетки в сцене. С помощью кнопки slice вы можете вырезать некоторые сетки, а с помощью кнопки all вы можете отобразить всю модель целиком. Мой код работает неправильно, когда я нажимаю кнопку среза, сетки центрируются, но когда я нажимаю ее снова, срезы возвращаются в исходное положение. То же самое с кнопкой «все» (она прыгает вверх и вниз). Я также открыт для совершенно разных решений для центрирования.
И вот код:
import "./styles.css";
import { useRef, useEffect } from "react";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import * as THREE from "three";
let camera;
let renderer;
var scene;
var villageMesh;
var mymeshes;
const centerObject = () => {
var objBbox = new THREE.Box3().setFromObject(villageMesh);
var helper = new THREE.BoundingBoxHelper(villageMesh, 0xff0000);
scene.add(helper);
const offset = new THREE.Vector3();
objBbox.getCenter(offset).negate();
villageMesh.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.position.copy(offset);
}
});
};
const addLight = (geometry, mat, x, y, z) => {
const light = new THREE.PointLight(0x404040, 4); // soft white light
light.position.set(x, y, z);
scene.add(light);
const lightSphere = new THREE.Mesh(geometry, mat);
lightSphere.position.set(x, y, z);
scene.add(lightSphere);
};
export default function App() {
const mountRef = useRef();
const onClick = () => {
villageMesh.children = mymeshes.slice(23, 24);
centerObject();
};
const onClickAll = () => {
villageMesh.children = [...mymeshes];
centerObject();
};
useEffect(() => {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.01,
100000
);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
if (mountRef.current.childNodes.length === 0) {
document.body.appendChild(renderer.domElement);
}
const controls = new OrbitControls(camera, renderer.domElement);
const sphereGeometry = new THREE.SphereGeometry(15, 32, 16);
const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
const axesHelper = new THREE.AxesHelper(10000);
scene.add(axesHelper);
addLight(sphereGeometry, sphereMaterial, 100, 100, 100);
camera.position.set(0, 100, 0);
// load Object
var objLoader = new OBJLoader();
objLoader.load(
"./assets/Street_environment_V01.obj",
function (object) {
villageMesh = object;
mymeshes = [...object.children];
scene.add(villageMesh);
centerObject();
},
function (xhr) {
console.log((xhr.loaded / xhr.total) * 100 "% loaded");
},
function (error) {
console.log("An error happened" error);
}
);
var animate = function () {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
};
animate();
}, []);
return (
<div>
<button onClick={onClick}>Slice</button>
<button onClick={onClickAll}>All</button>
<div ref={mountRef}></div>
</div>
);
}