Reset position of grouped objects

Hi all,

I’ve created a script that sets up walls based on x,y coordinates. They are grouped together but now they are positioned far from 0,0,0.

Can I reposition the group to 0,0,0 with all its children?

import * as THREE from "three";

import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import data from "./data.json";

let camera, controls, scene, renderer;
const WALL_HEIGHT = 3;

// Function to create a wall
function createWall(x1, y1, x2, y2, height) {
  const length = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
  const geometry = new THREE.PlaneGeometry(length, height);
  const material = new THREE.MeshBasicMaterial({
    color: 0xffffff, // Using the colors array for variety
    side: THREE.DoubleSide,
  });
  const wall = new THREE.Mesh(geometry, material);
  wall.castShadow = true;
  wall.receiveShadow = true;

  const centerX = (x1 + x2) / 2;
  const centerY = (y1 + y2) / 2;
  const angle = Math.atan2(y2 - y1, x2 - x1);

  // Correcting the position and rotation for standing up walls
  wall.position.set(centerX, height / 2, centerY); // Adjust Y for height / 2 to elevate it
  wall.rotation.set(0, -angle, 0); // Rotate around Y-axis to align properly

  return wall;
}

init();
animate();

function init() {
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0xcccccc);

  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
  const size = 10;
  const divisions = 5;

  const gridHelper = new THREE.GridHelper(size, divisions);
  scene.add(gridHelper);

  camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    1000
  );
  camera.position.set(1, 1, 7);

  // controls

  controls = new OrbitControls(camera, renderer.domElement);
  controls.listenToKeyEvents(window); // optional

  controls.enableDamping = true;
  controls.dampingFactor = 0.05;

  controls.screenSpacePanning = false;

  controls.minDistance = 1;
  controls.maxDistance = 500;

  const geometry = new THREE.ConeGeometry(10, 30, 4, 1);
  const material = new THREE.MeshPhongMaterial({
    color: 0xffffff,
    flatShading: true,
  });

  // lights

  const ambientLight = new THREE.AmbientLight(0x555555);
  scene.add(ambientLight);

  // Create and add walls based on your coordinates
  const wallNodes = [
    { id: 1, x: 20, y: 22 },
    { id: 2, x: 27.3, y: 22 },
    { id: 3, x: 27.3, y: 25 },
    { id: 4, x: 20, y: 25 },
  ];

  const group = new THREE.Group();
  for (let i = 0; i < wallNodes.length; i++) {
    const startNode = wallNodes[i];
    const endNode = wallNodes[(i + 1) % wallNodes.length]; // Loop back to the first node after the last
    const wall = createWall(
      startNode.x,
      startNode.y,
      endNode.x,
      endNode.y,
      WALL_HEIGHT
    );
    group.add(wall);
  }
  group.position.set(0, WALL_HEIGHT / 2, 0);
  scene.add(group);
  // Calculate the bounding box of the group
  const box = new THREE.Box3().setFromObject(group);

  // Calculate the center of the bounding box
  const center = box.getCenter(new THREE.Vector3());

  // Adjust camera position to ensure the group is in view
  // This example moves the camera back along the z-axis and up slightly
  camera.position.set(center.x, center.y + 5, center.z + 10);

  // Use OrbitControls to target the center of the group
  controls.target.set(center.x, center.y, center.z);

  // Update the camera to look at the center of the group
  camera.lookAt(center.x, center.y, center.z);

  const pointLight = new THREE.PointLight(0xff0000, 1, 100);
  pointLight.position.set(center.x, center.y, center.z);
  scene.add(pointLight);

  const sphereSize = 1;
  const pointLightHelper = new THREE.PointLightHelper(pointLight, sphereSize);
  scene.add(pointLightHelper);

  //

  window.addEventListener("resize", onWindowResize);
}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {
  requestAnimationFrame(animate);

  controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true

  render();
}

function render() {
  renderer.render(scene, camera);
}

apparently doing this

  new THREE.Box3()
    .setFromObject(group)
    .getCenter(group.position)
    .multiplyScalar(-1);

did the trick

1 Like