this green border is my grid so I want to add a button there and when I click on the buttons like left bottom right and left I want to move that grid according to the actions and load panels into it how can I do it?
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
let v1 = new THREE.Vector3();
let raycaster = new THREE.Raycaster();
const deleteIconGeometry = new THREE.BoxGeometry(0.3, 0.3, 0.3); // small cube for delete icon
const deleteIconMaterial = new THREE.MeshStandardMaterial({ color: "red" });
export default class PanelGrid extends THREE.Object3D {
bounds = new THREE.Box3();
size = new THREE.Vector3();
selectionSize = new THREE.Vector3();
constructor({ modules, deleteObject }) {
super();
this.modules = modules;
this.selectionMesh = planeMesh.clone();
this.add(this.selectionMesh);
this.defaultOffset = { x: 1, y: 1 };
this.deleteObject = deleteObject;
}
setSize(x, y, z) {
this.size.set(x, y, z);
}
recomputeOccupancy({ targets }) {
let s = this.size;
let panelX = 1.4;
let panelY = 2;
this.occupancy = PanelGrid.raycastGrid({
root: this.children[0],
targets,
step: {
x: panelX / s.x,
y: panelY / -s.y,
},
offset: this.defaultOffset,
});
return this.occupancy;
}
static raycastGrid({ root, targets, step }) {
let down = new THREE.Vector3(0, -1, 0);
let results = [];
let rows = 0;
let cols;
let nx = (1 / step.x) | 0;
let ny = (1 / step.y) | 0;
let margx = (1 - nx * step.x) * 0.5;
let margy = (1 - ny * step.y) * 0.5;
for (let x = step.x * 0.5 + margx; x < 1 - step.x * 0.5; x += step.x) {
cols = 0;
for (let z = step.y * 0.5 + margy; z <= 1 - step.y * 0.5; z += step.y) {
const origin = new THREE.Vector3(x, z, 1.1);
root && root.localToWorld(origin);
raycaster.set(origin, down);
let res = {
origin,
object: targets[0],
};
results.push(res);
const intersects = raycaster.intersectObjects(targets, true);
if (intersects.length > 0) {
res.point = intersects[0].point.clone();
res.normal = intersects[0].normal.clone();
res.object = intersects[0].object;
const validPlanarThresholdWS = 1;
if (res.origin.distanceTo(res.point) < validPlanarThresholdWS)
res.isSupported = true;
}
cols++;
}
rows++;
}
return {
results,
rows,
cols,
root,
};
}
disposeOccupancy() {
if (!this.occupancy) return;
let occupancy = this.occupancy;
occupancy.results.forEach((res) => {
res && res.indicator && res.indicator.parent.remove(res.indicator);
});
occupancy.results.length = 0;
}
redrawOccupancy() {
let occupancy = this.occupancy;
let results = occupancy.results;
let normal = v1.set(0, 0, 1).applyQuaternion(occupancy.root.quaternion);
for (const result of results) {
if (!result) continue;
if (!result.object.isMesh) continue;
const { boundsTree } = result.object.geometry;
const module = this.modules[0].clone();
let panel = new THREE.Object3D();
panel.position.copy(result.origin);
panel.rotation.setFromQuaternion(occupancy.root.parent.quaternion);
panel.updateMatrix();
result.object.attach(panel);
panel.updateMatrixWorld();
let moduleIsObstructed = (module) => {
let box = new THREE.Box3().setFromObject(module);
return boundsTree.intersectsBox(box, panel.matrix);
};
let moduleIsSupported = (module) => {
let box = new THREE.Box3().setFromObject(module);
let panelThickness = box.max.z - box.min.z;
const supportThickness = panelThickness;
const supportLength = panelThickness * 20;
let c0 = box.clone();
c0.max.x = c0.min.x + supportThickness;
c0.max.y = c0.min.y + supportThickness;
c0.min.z = c0.max.z - supportLength;
if (!boundsTree.intersectsBox(c0, panel.matrix)) return false;
let c1 = box.clone();
c1.min.x = c1.max.x - supportThickness;
c1.max.y = c1.min.y + supportThickness;
c1.min.z = c1.max.z - supportLength;
if (!boundsTree.intersectsBox(c1, panel.matrix)) return false;
let c2 = box.clone();
c2.min.x = c2.max.x - supportThickness;
c2.min.y = c2.max.y - supportThickness;
c2.min.z = c2.max.z - supportLength;
if (!boundsTree.intersectsBox(c2, panel.matrix)) return false;
let c3 = box.clone();
c3.max.x = c3.min.x + supportThickness;
c3.min.y = c3.max.y - supportThickness;
c3.min.z = c3.max.z - supportLength;
if (!boundsTree.intersectsBox(c3, panel.matrix)) return false;
return true;
};
if (
!result.isSupported ||
moduleIsObstructed(module) ||
!moduleIsSupported(module)
) {
for (let i = 1; i < this.modules.length; i++) {
let submodule = this.modules[i].clone();
if (!moduleIsObstructed(submodule) && moduleIsSupported(module))
panel.add(submodule);
}
} else {
module.children[0].originalMaterial = module.children[0].material;
panel.add(module);
panel.name = "supported";
if (this.deleteObject) {
const deleteIcon = this.deleteObject.clone();
deleteIcon.name = "deleteIcon";
const box = new THREE.Box3().setFromObject(panel);
const panelSize = new THREE.Vector3();
box.getSize(panelSize);
// deleteIcon.rotation.setFromQuaternion(panel.quaternion);
deleteIcon.updateMatrix();
// deleteIcon.scale.set(
// 0.0025 * panelSize.x,
// 0.01 * panelSize.y,
// 0.005 * panelSize.z
// );
deleteIcon.position.set(
panelSize.x / 2 - deleteIcon.scale.x / 2,
panelSize.y / 2 - deleteIcon.scale.y / 2,
0.015
);
// panel.add(deleteIcon);
}
}
this.attach(panel);
result.indicator = panel;
panel.updateMatrixWorld(true);
panel.traverse((e) => (e.matrixAutoUpdate = false));
}
}
}
const baseMetal = 0.0;
const baseRough = 0.8;
PanelGrid.selectedStateMaterial = new THREE.MeshStandardMaterial({
metalness: baseMetal,
roughness: baseRough,
transparent: true,
opacity: 0.4,
depthWrite: false,
color: "teal",
});
PanelGrid.collidedStateMaterial = new THREE.MeshStandardMaterial({
metalness: baseMetal,
roughness: baseRough,
transparent: true,
depthWrite: false,
opacity: 0.15,
color: "red",
});
PanelGrid.nonCollidedStateMaterial = new THREE.MeshStandardMaterial({
metalness: baseMetal,
roughness: baseRough,
transparent: true,
depthWrite: false,
opacity: 0.9,
color: "green",
});
PanelGrid.deselectedStateMaterial = new THREE.MeshStandardMaterial({
metalness: baseMetal,
roughness: baseRough,
transparent: true,
depthWrite: false,
opacity: 0.1,
color: "blue",
});
let planeMesh = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
PanelGrid.selectedStateMaterial
);
planeMesh.geometry.translate(0.5, 0.5, 0.5);
planeMesh.geometry.computeBoundingBox();
this is the panel grid code please check and let me know if anyone can help me it will be big help
thanks