I have a basic setup in Three.js involving some planes. Currently, when clicked, the planes move to random positions.
Instead of the random movement, I want the planes to transition into a new grid that is perpendicular to the camera, aligning the projected grid's x and y axes parallel to the screen's x and y axes.
Here is the current scene:
// Scene setup
var scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
// Camera setup
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.01, 10000);
// Position the camera
camera.position.set(51.389, -451.056, 839.455);
var rotObjectMatrix = new THREE.Matrix4();
var q = {_x: 0.0184, _y: -0.2122, _z: 0.9770, _w: -0.0081};
rotObjectMatrix.makeRotationFromQuaternion(q);
camera.quaternion.setFromRotationMatrix(rotObjectMatrix);
camera.up.set(0.00806, -0.91008, -0.41432);
// Renderer setup
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Controls setup
var controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.target.set(19.053, -111.316, 93.996);
// Lights setup
var ambientLight = new THREE.AmbientLight(0xeeeeee);
scene.add(ambientLight);
// Render function
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
controls.update();
};
// Grid creation
var grid = new THREE.GridHelper(2000, 20, 0x000000, 0x000000);
grid.material.opacity = 0.2;
grid.material.transparent = true;
grid.rotation.x = -Math.PI;
scene.add(grid);
// Adding planes
planes = [];
for (var i=0; i<2**10; i++) {
var geometry = new THREE.PlaneGeometry(20, 20, 32);
var material = new THREE.MeshBasicMaterial({color: 0xff0000, side: THREE.DoubleSide});
var plane = new THREE.Mesh(geometry, material);
var x = ((i % 2**5) * 40) - (2**5 * 40)/2;
var z = (Math.floor(i/2**5) * 40) - (2**5 * 40)/2;
plane.position.set(x, 0, z);
scene.add(plane);
planes.push(plane);
}
// Transition for planes on click
document.querySelector('body').addEventListener('click', function() {
planes.forEach(function(plane) {
// Placeholder
plane.position.set(
Math.random() * 500 - (Math.random() * 500)/2,
0,
Math.random() * 500 - (Math.random() * 500)/2,
)
})
})
render();
html, body { width: 100%; height: 100%; background: #000; }
body { margin: 0; overflow: hidden; }
canvas { width: 100%; height: 100%; }
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js'></script>
<script src='https://threejs.org/examples/js/controls/TrackballControls.js'></script>
The following code snippet gets close to the desired projection but doesn't tilt the planes to be perpendicular to the camera:
planes.forEach(function(plane) {
// Approach similar to the discussed projection
plane.position.set(
plane.position.x,
plane.position.z,
0,
)
})
If anyone has suggestions on achieving the described projection or any other input, it would be greatly appreciated!