I'm trying to rotate objects around the cg of bounding box, but they are still rotating around the [0,0,0] origin. The code is shown below :
import React, { forwardRef, useEffect, useRef, useState } from "react";
import { objects, library, building } from "./config";
import Block from "./Block";
import { TransformControls, useHelper } from "@react-three/drei";
import { Box3, BoxHelper, LineSegments, Vector3 } from "three";
import { VertexNormalsHelper } from "three/examples/jsm/helpers/VertexNormalsHelper";
import { useThree } from "@react-three/fiber";
import { Selection } from "./Selection";
import { useControls } from "leva";
const BlockContainer = (props, ref) => {
const { gl } = useThree();
const [File, setFile] = useState(null);
const [SelectedObjects, setSelectedObjects] = useState([]);
const [AllBlocks, setAllBlocks] = useState([]);
const [CG, setCG] = useState([0.0, 0.0, 0.0]);
const { mode, ...config } = useControls({
mode: { options: ["translate", "rotate"] },
});
const blockRefs = useRef([]);
const selectedRef = useRef();
const unselectedRef = useRef();
const transformRef = useRef();
const rotationRef = useRef();
const helperRef = useRef();
// helpers
useHelper(selectedRef, BoxHelper, "green");
useHelper(true, BoxHelper, "red");
useHelper(true, VertexNormalsHelper, "blue");
useEffect(() => {
setFile(objects);
}, []);
const initBlocks = (bref) => {
setAllBlocks((prev) => [...prev, bref.current]);
};
const getCenter = (objects) => {
const center = objects
.map((i) => [
i?.matrixWorld.elements[12] || 0.0,
i?.matrixWorld.elements[13] || 0.0,
i?.matrixWorld.elements[14] || 0.0,
])
.reduce(
(acc, curr) => [acc[0] + curr[0], acc[1] + curr[1], acc[2] + curr[2]],
[0, 0, 0]
)
.map((sum) => sum / objects.length);
return center;
};
useEffect(() => {
if (SelectedObjects.length > 1) {
const center = getCenter(SelectedObjects);
const center1 = [
center[0] -
transformRef.current.offset.x -
transformRef.current.positionStart.x,
center[1] -
transformRef.current.offset.y -
transformRef.current.positionStart.y,
center[2] -
transformRef.current.offset.z -
transformRef.current.positionStart.z,
];
setCG(center);
AllBlocks.forEach((b) => {
if (SelectedObjects.includes(b)) {
selectedRef.current.attach(b);
} else {
unselectedRef.current.attach(b);
selectedRef.current.remove(b);
}
});
transformRef.current.attach(selectedRef.current);
} else if (SelectedObjects.length === 1) {
transformRef.current.attach(SelectedObjects[0]);
}
}, [SelectedObjects, AllBlocks, mode]);
return (
<>
<Block
data={building.coreshell}
url={library[building.coreshell.itemId].url}
onSelect={(sel) => {}}
key={building.coreshell.id}
onInit={(bref) => {}}
Offset={new Vector3(0, 0, 0)}
/>
<TransformControls
ref={transformRef}
onChange={(ev) => {}}
onMouseUp={(ev) => {
console.log("position", transformRef.current.position);
console.log("positionStart", transformRef.current.positionStart);
console.log("offset", transformRef.current.offset);
}}
mode={mode}
enabled={SelectedObjects.length > 0}
scale={SelectedObjects.length > 0 ? 0.5 : 0.0}
/>
<group ref={selectedRef} />
<group ref={unselectedRef} />
{building.blocks.map((i, index) => (
<Block
data={i}
Offset={null}
url={library[i.itemId].url}
onInit={initBlocks}
exSelected={false}
onSelect={(sel) => {
setSelectedObjects((prev) => {
if (prev.includes(sel.current)) {
return prev.filter((h) => h !== sel.current);
} else {
return [...prev, sel.current];
}
});
}}
key={`block_togo_${i.id}`}
/>
))}
</>
);
};
export default BlockContainer;
I have trying getting the center vector of the selected objects, then move the <TransformControls ../>
into that position. I expected that the group of objects will rotate around this center. but what happens is that they rotate around the origin.