I'm adding a window object, which is a GLTF model. Depending on the window's size, I place a mesh object behind it to simulate glass (to make the interior of the hall visible). This works correctly on one side of the hall (image #1), but on the other sides of the hall, it doesn't work as intended (image #2).
import { useState, useEffect } from 'react';
import * as THREE from 'three';
import { Shape, ShapeGeometry, MeshBasicMaterial } from 'three';
import { useSpring, animated } from '@react-spring/web'
import { useDrag } from 'react-use-gesture';
import { useThree } from "@react-three/fiber";
const _ = require("lodash");
function DraggableWindow(props) {
const { size, viewport } = useThree();
const aspect = size.width / viewport.width;
let sub;
if(props.direction === 'back' || props.direction === 'front'){
sub = props.elementPositionToSub;
}else if(props.direction === 'left' || props.direction === 'right' ){
sub = props.elementPositionToSubSides;
}
let glassRotation;
if(props.direction === 'front'){
}else if(props.direction === 'back'){
}else if(props.direction === 'left'){
glassRotation = [0, 0, Math.PI];
}else if(props.direction === 'right'){
glassRotation = [0, Math.PI, 0];
}
const [position, setPosition] = useState((props.direction === 'back' || props.direction === 'front' ? [props.newposition.x, props.newposition.y, props.ModelPos] : [props.ModelPos, props.newposition.y, props.newposition.z]));
const [rotation, setRotation] = useState([props.newrotation.x, props.newrotation.y, props.newrotation.z]);
const [scale, setScale] = useState(props.scaleX !== undefined ? [props.scaleX, props.scaleY, 25] : props.scale);
const [show, setShow] = useState(false);
const [draggable, setDraggable] = useState(true);
let circlePosition, circleRotation, xRotation;
if(props.direction === 'front' || props.direction === 'back'){
if(props.obj === '1_window'){
circlePosition = [0, 1.7, -0.09];
circleRotation = [0, 3.2, 0];
xRotation = [0, 0, 0];
}else if(props.obj === '2_window'){
circlePosition = [1.9, 2.2, 0.07];
circleRotation = [0, 0, 0];
xRotation = [0, 0, 0];
}else if(props.obj === '3_window'){
circlePosition = [2.21, -0.02, -0.05];
circleRotation = [0, -Math.PI / 2, 0];
xRotation = [0, -Math.PI / 2, Math.PI / 4];
}else if(props.obj === '4_window'){
circlePosition = [3.95, 1.65, 0.02];
circleRotation = [0, 0, 0];
xRotation = [0, 0, 0];
}
}else{
if(props.obj === '1_window'){
circlePosition = [1.2, 1.7, 0.02];
circleRotation = [0, 0, 0];
xRotation = [0, 0, 0];
}else if(props.obj === '2_window'){
circlePosition = [0, 2.2, -0.14];
circleRotation = [0, Math.PI, 0];
xRotation = [0, 0, 0];
}else if(props.obj === '3_window'){
circlePosition = [0.05, 0.09, -0.05];
circleRotation = [0, Math.PI / 2, 0];
xRotation = [0, -Math.PI / 2, Math.PI / 4];
}else if(props.obj === '4_window'){
circlePosition = [0.65, 1.65, -0.09];
circleRotation = [0, Math.PI, 0];
xRotation = [0, 0, 0];
}
}
const bind = useDrag(
({ active, offset: [x, y] }) => {
if(draggable){
if(props.direction === 'front'){
const [, , z] = position;
setPosition([x / aspect, -y / aspect, props.ModelPos - sub]);
props.setCameraMovement(!active);
}else if (props.direction === 'back'){
const [, , z] = position;
setPosition([-x / aspect, -y / aspect, props.ModelPos + sub]);
props.setCameraMovement(!active);
}else if (props.direction === 'left'){
const [z, , ] = position;
if(props.obj === '4_window'){
setPosition([props.ModelPos - (sub + 3.5), -y / aspect, x / aspect]);
}else{
setPosition([props.ModelPos - sub, -y / aspect, x / aspect]);
}
props.setCameraMovement(!active);
}else if (props.direction === 'right'){
const [z, , ] = position;
if(props.obj === '4_window'){
setPosition([props.ModelPos + (sub + 3.5), -y / aspect, -x / aspect]);
}else{
setPosition([props.ModelPos + sub, -y / aspect, -x / aspect]);
}
props.setCameraMovement(!active);
}
}
},
{ pointerEvents: true }
);
useEffect(() => {
if(props.direction === 'front'){
setPosition([position[0], position[1], props.ModelPos - sub]);
}else if(props.direction === 'back'){
setPosition([position[0], position[1], props.ModelPos + sub]);
}else if(props.direction === 'left'){
if(props.obj === '4_window'){
setPosition([props.ModelPos - (sub + 3.5), position[1], position[2]]);
}else{
setPosition([props.ModelPos - sub, position[1], position[2]]);
}
}else if(props.direction === 'right'){
if(props.obj === '4_window'){
setPosition([props.ModelPos + (sub + 3.5), position[1], position[2]]);
}else{
setPosition([props.ModelPos + sub, position[1], position[2]]);
}
}
}, [props.ModelPos]);
const changeYScale = (e) => {
// Store the initial position of the mouse\
setDraggable(false)
const initialY = e.clientY;
const onPointerMove = (e) => {
const deltaY = e.clientY - initialY;
setScale([scale[0], scale[1] - deltaY, scale[2]])
setPosition(position)
};
const onPointerUp = () => {
document.removeEventListener('pointermove', onPointerMove);
document.removeEventListener('pointerup', onPointerUp);
};
document.addEventListener('pointermove', onPointerMove);
document.addEventListener('pointerup', onPointerUp);
}
const changeXScale = (e) => {
// Store the initial position of the mouse\
setDraggable(false)
const initialX = e.clientX;
const onPointerMove = (e) => {
const deltaX = e.clientX - initialX;
setScale([scale[0] + deltaX, scale[1], scale[2]])
if(props.direction === 'front' || props.direction === 'back'){
setPosition(position)
}else if(props.direction === 'left'){
setPosition([position[0] - 3.5, position[1], position[2]])
}else if(props.direction === 'right'){
setPosition([position[0] + 3.5, position[1], position[2]])
}
};
const onPointerUp = () => {
document.removeEventListener('pointermove', onPointerMove);
document.removeEventListener('pointerup', onPointerUp);
};
document.addEventListener('pointermove', onPointerMove);
document.addEventListener('pointerup', onPointerUp);
}
const Rectangle = () => {
const rectangleShape = new THREE.Shape();
rectangleShape.moveTo(0, 0);
rectangleShape.lineTo(0, 1);
rectangleShape.lineTo(1, 1);
rectangleShape.lineTo(1, 0);
rectangleShape.lineTo(0, 0);
const geometry = new THREE.ShapeGeometry(rectangleShape);
return (
<mesh>
<geometry attach="geometry" args={[geometry]} />
<material attach="material" color="blue" />
</mesh>
);
};
return (
<mesh
onPointerEnter={(e) => {
const canvas = document.querySelector('canvas');
if(e.object.parent.type === 'Group'){
canvas.style.cursor = 'pointer';
}else{
canvas.style.cursor = 'grab';
}
}}
onPointerLeave={() => { const canvas = document.querySelector('canvas'); canvas.style.cursor = null }}
onClick={() => setShow(true)}
onPointerMissed={() => setShow(false)}
position={position}
rotation={rotation}
{...bind()}
>
<primitive object={props.window} scale={scale}>
{(show ? <group position={circlePosition} rotation={(props.obj === '3_window' ? [0, 0, 1.6] : [0, 0, 0.8])} onClick={() => props.handleDeleteWindow(props.index)}>
<mesh rotation={circleRotation}>
<circleBufferGeometry args={[0.15, 32]} /> {/* Ustaw odpowiednią średnicę i ilość segmentów */}
<meshStandardMaterial color="red" />
</mesh>
<mesh rotation={xRotation}>
<boxBufferGeometry args={[0.03, 0.2, 0.01]} />
<meshStandardMaterial color="white" />
</mesh>
<mesh rotation={xRotation}>
<boxBufferGeometry args={[0.2, 0.03, 0.01]} />
<meshStandardMaterial color="white" />
</mesh>
</group> : '')}
{/* transparent element */}
<mesh position={[2.3, 0.8, 0]} rotation={glassRotation}>
<planeBufferGeometry attach="geometry" args={[3.2, 1.6]} />
<meshPhongMaterial side={THREE.FrontSide} color="#999999" transparent={true} opacity={0.5} premultipliedAlpha={true}/>
</mesh>
{(show && props.obj === '4_window' ?
<mesh
onPointerDown={(e) => {changeYScale(e)}}
onPointerLeave={() => {setDraggable(true); props.setCameraMovement(!props.cameraMovement);}}
scale={[0.6, 0.3, 0.5]} rotation={(props.direction === 'front' || props.direction === 'back' ? [0, 0, 0] : (props.direction === 'left' ? [Math.PI, 0, Math.PI] : [Math.PI, 0, Math.PI]))} position={[2.26, 1.9, 0]}
>
<shapeGeometry/>
<meshStandardMaterial color="rgba(0, 0, 0, 0.2)"/>
</mesh>
: '')}
{(show && props.obj === '4_window' ?
<mesh onPointerDown={(e) => {changeXScale(e)}} onPointerLeave={() => {setDraggable(true); props.setCameraMovement(!props.cameraMovement);}} scale={[0.6, 0.3, 0.5]} rotation={(props.direction === 'front' || props.direction === 'back' ? [0, 0, -Math.PI / 2] : (props.direction === 'left' ? [Math.PI, 0, Math.PI / 2] : [Math.PI, 0, Math.PI / 2]))} position={(props.direction === 'front' || props.direction === 'back' ? [4.195, 0.9, -0.1] : [0.4, 0.9, -0.1])}>
<shapeGeometry/>
<meshStandardMaterial color="rgba(0, 0, 0, 0.2)"/>
</mesh>
: '')}
</primitive>
</mesh>
)
}
Why does the object work correctly when added to one side of the hall, but not for the other sides?