And everything is fine if the object is not moved: without moving
But if you move, then the lines remain in place: after moving
If I try to get the world coordinates of points after moving, then I see the same picture: after moving + localToWorld
If I update matrix world for cube, then I see this: after moving + localToWorld + updateMatrixWorld
var scene = new THREE.Scene();
scene.background = new THREE.Color().setStyle('#e0e0e0');
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 100000);
camera.position.set(0, 500, 3000);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
///////////////////////CREATE CUBE////////////////////////////////
const cube = new THREE.Mesh(
new THREE.BoxBufferGeometry(1000, 1000, 1000),
new THREE.MeshBasicMaterial({
color: 'red',
transparent: true,
opacity: 0.4
})
);
scene.add(cube);
//MOVE
cube.position.set(100, 100, 100);
//UPDATE
cube.updateMatrixWorld(true);
//GET EDGE LINES(THREE.Line3) FOR EDGES OF FACES
const lines = getLinesFromFaces(cube);
//CONVERT FROM LOCAL TO WORLD
lines.map(l => {
//l.applyMatrix4(cube.matrixWorld);
//l.start.applyMatrix4(cube.matrixWorld);
//l.end.applyMatrix4(cube.matrixWorld);
cube.localToWorld(l.start);
cube.localToWorld(l.end);
});
//DRAW
drawLines(lines);
function drawLines(lines) {
for (let i = 0; i < lines.length; i += 1) {
addLine(lines[i].start, lines[i].end);
}
}
function addLine(p1, p2) {
const material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
const points = [p1, p2];
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const line = new THREE.Line(geometry, material);
scene.add(line);
}
function getLinesFromFaces(object) {
const facesWithPos = getFacesWithPos(object.geometry);
const lines = [];
for (let i = 0; i < facesWithPos.length; i += 1) {
const f = facesWithPos[i];
const lineAB = new THREE.Line3(f.a, f.b);
let isExist = false;
isExist = lines.some(l => {
return (l.start.equals(lineAB.start) && l.end.equals(lineAB.end)) ||
(l.start.equals(lineAB.end) && l.end.equals(lineAB.start));
});
if (!isExist) lines.push(lineAB);
const lineBC = new THREE.Line3(f.b, f.c);
isExist = false;
isExist = lines.some(l => {
return (l.start.equals(lineBC.start) && l.end.equals(lineBC.end)) ||
(l.start.equals(lineBC.end) && l.end.equals(lineBC.start));
});
if (!isExist) lines.push(lineBC);
const lineCA = new THREE.Line3(f.c, f.a);
isExist = false;
isExist = lines.some(l => {
return (l.start.equals(lineCA.start) && l.end.equals(lineCA.end)) ||
(l.start.equals(lineCA.end) && l.end.equals(lineCA.start));
});
if (!isExist) lines.push(lineCA);
}
return lines;
}
function getFacesWithPos(geometry) {
const faces = getFaces(geometry);
const facesWithPos = [];
const position = geometry.getAttribute('position');
for (let i = 0; i < faces.length; i += 1) {
const f = faces[i];
facesWithPos.push({
a: new THREE.Vector3(position.array[f.a * 3], position.array[f.a * 3 + 1], position.array[f.a * 3 + 2]),
b: new THREE.Vector3(position.array[f.b * 3], position.array[f.b * 3 + 1], position.array[f.b * 3 + 2]),
c: new THREE.Vector3(position.array[f.c * 3], position.array[f.c * 3 + 1], position.array[f.c * 3 + 2])
});
}
return facesWithPos;
}
function getFaces(geometry) {
const faces = [];
const index = geometry.getIndex();
for (let i = 0; i < index.count; i += 3) {
faces.push({
a: index.getX(i),
b: index.getX(i + 1),
c: index.getX(i + 2)
});
}
return faces;
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.117.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.117.0/examples/js/controls/OrbitControls.js"></script>
How to get world coordinates? what am I doing wrong?
Some of the line points were common objects. If you apply localToWorld to them, then the method was applied to them several times and the result was not correct. Below is the solution
var scene = new THREE.Scene();
scene.background = new THREE.Color().setStyle('#e0e0e0');
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 100000);
camera.position.set(0, 500, 3000);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
///////////////////////CREATE CUBE////////////////////////////////
const cube = new THREE.Mesh(
new THREE.BoxBufferGeometry(1000, 1000, 1000),
new THREE.MeshBasicMaterial({
color: 'red',
transparent: true,
opacity: 0.4
})
);
scene.add(cube);
//MOVE
cube.position.set(100, 100, 100);
//UPDATE
cube.updateMatrixWorld(true);
//GET EDGE LINES(THREE.Line3) FOR EDGES OF FACES
const lines = getLinesFromFaces(cube);
//CONVERT FROM LOCAL TO WORLD
lines.map(l => {
//l.applyMatrix4(cube.matrixWorld);
//l.start.applyMatrix4(cube.matrixWorld);
//l.end.applyMatrix4(cube.matrixWorld);
cube.localToWorld(l.start);
cube.localToWorld(l.end);
});
//DRAW
drawLines(lines);
function drawLines(lines) {
for (let i = 0; i < lines.length; i += 1) {
addLine(lines[i].start, lines[i].end);
}
}
function addLine(p1, p2) {
const material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
const points = [p1, p2];
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const line = new THREE.Line(geometry, material);
scene.add(line);
}
function getLinesFromFaces(object) {
const facesWithPos = getFacesWithPos(object.geometry);
const lines = [];
for (let i = 0; i < facesWithPos.length; i += 1) {
const f = facesWithPos[i];
const lineAB = new THREE.Line3(f.a, f.b);
let isExist = false;
isExist = lines.some(l => {
return (l.start.equals(lineAB.start) && l.end.equals(lineAB.end)) ||
(l.start.equals(lineAB.end) && l.end.equals(lineAB.start));
});
if (!isExist) lines.push(lineAB.clone());
const lineBC = new THREE.Line3(f.b, f.c);
isExist = false;
isExist = lines.some(l => {
return (l.start.equals(lineBC.start) && l.end.equals(lineBC.end)) ||
(l.start.equals(lineBC.end) && l.end.equals(lineBC.start));
});
if (!isExist) lines.push(lineBC.clone());
const lineCA = new THREE.Line3(f.c, f.a);
isExist = false;
isExist = lines.some(l => {
return (l.start.equals(lineCA.start) && l.end.equals(lineCA.end)) ||
(l.start.equals(lineCA.end) && l.end.equals(lineCA.start));
});
if (!isExist) lines.push(lineCA.clone());
}
return lines;
}
function getFacesWithPos(geometry) {
const faces = getFaces(geometry);
const facesWithPos = [];
const position = geometry.getAttribute('position');
for (let i = 0; i < faces.length; i += 1) {
const f = faces[i];
facesWithPos.push({
a: new THREE.Vector3(position.array[f.a * 3], position.array[f.a * 3 + 1], position.array[f.a * 3 + 2]),
b: new THREE.Vector3(position.array[f.b * 3], position.array[f.b * 3 + 1], position.array[f.b * 3 + 2]),
c: new THREE.Vector3(position.array[f.c * 3], position.array[f.c * 3 + 1], position.array[f.c * 3 + 2])
});
}
return facesWithPos;
}
function getFaces(geometry) {
const faces = [];
const index = geometry.getIndex();
for (let i = 0; i < index.count; i += 3) {
faces.push({
a: index.getX(i),
b: index.getX(i + 1),
c: index.getX(i + 2)
});
}
return faces;
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.117.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.117.0/examples/js/controls/OrbitControls.js"></script>