Im trying to make a Portal class out of the threejs example:
https://threejs.org/examples/?q=portal#webgl_portal
But im getting some errors that Im not understanding.
This is my class
class Portal{
constructor(size, position1, position2, rotation1, rotation2) {
this.geometry = new Plane(size.width, size.height);
this.portalTexture1 = new THREE.WebGLRenderTarget( 256, 256 );
this.portalTexture2 = new THREE.WebGLRenderTarget( 256, 256 );
this.material1 = new THREE.MeshBasicMaterial({map:this.portalTexture1.texture});
this.material2 = new THREE.MeshBasicMaterial({map:this.portalTexture2.texture});
this.portalMesh1 = new THREE.Mesh(this.geometry, this.material1);
this.portalMesh2 = new THREE.Mesh(this.geometry, this.material2);
this.portalMesh1.position.set(position1.x,position1.y,position1.z);
this.portalMesh2.position.set(position2.x,position2.y,position2.z);
this.portalMesh1.rotation.set(rotation1.x, rotation1.y, rotation1.z);
this.portalMesh2.rotation.set(rotation2.x, rotation2.y, rotation2.z);
this.portalCamera = new THREE.PerspectiveCamera( 45, 1.0, 0.1, 500.0 );
this.bottomLeftCorner = new THREE.Vector3();
this.bottomRightCorner = new THREE.Vector3();
this.topLeftCorner = new THREE.Vector3();
this.reflectedPosition = new THREE.Vector3();
this.meshGroup = new THREE.Group();
this.meshGroup.add(this.portalCamera);
this.meshGroup.add(this.portalMesh1);
this.meshGroup.add(this.portalMesh2);
}
renderPortal(renderer, camera, scene, thisPortalMesh, otherPortalMesh, thisPortalTexture) {
// set the portal camera position to be reflected about the portal plane
thisPortalMesh.worldToLocal( this.reflectedPosition.copy( camera.position ) );
this.reflectedPosition.x *= - 1.0;
this.reflectedPosition.z *= - 1.0;
otherPortalMesh.localToWorld( this.reflectedPosition );
this.portalCamera.position.copy( this.reflectedPosition );
// grab the corners of the other portal
// - note: the portal is viewed backwards; flip the left/right coordinates
otherPortalMesh.localToWorld( this.bottomLeftCorner.set( 50.05, - 50.05, 0.0 ) );
otherPortalMesh.localToWorld( this.bottomRightCorner.set( - 50.05, - 50.05, 0.0 ) );
otherPortalMesh.localToWorld( this.topLeftCorner.set( 50.05, 50.05, 0.0 ) );
// set the projection matrix to encompass the portal's frame
CameraUtils.frameCorners( this.portalCamera, this.bottomLeftCorner, this.bottomRightCorner, this.topLeftCorner, false );
// render the portal
thisPortalTexture.texture.encoding = renderer.outputEncoding;
renderer.setRenderTarget( thisPortalTexture );
renderer.state.buffers.depth.setMask( true ); // make sure the depth buffer is writable so it can be properly cleared, see #18897
if ( renderer.autoClear === false ) renderer.clear();
thisPortalMesh.visible = false; // hide this portal from its own rendering
console.log(scene)
renderer.render( scene, this.portalCamera );
thisPortalMesh.visible = true; // re-enable this portal's visibility for general rendering
}
update(renderer,scene,camera){
this.renderPortal(renderer,scene,camera,this.portalMesh1,this.portalMesh2,this.portalTexture1);
this.renderPortal(renderer,scene,camera,this.portalMesh2,this.portalMesh1,this.portalTexture2);
}
getMesh() {
return this.meshGroup;
}
}
And this is my main Application
class Application {
constructor() {
this.objects = [];
this.createScene();
}
createScene() {
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(60,
window.innerWidth / window.innerHeight, 0.1, 2000);
this.camera.position.z = 20;
const container = document.getElementById( 'container' );
this.renderer = new THREE.WebGLRenderer( { antialias: true } );
this.renderer.setPixelRatio( window.devicePixelRatio );
this.renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( this.renderer.domElement );
this.renderer.localClippingEnabled = true;
document.body.appendChild(this.renderer.domElement);
const ambientLight = new THREE.AmbientLight(0xfdffe1, 0.4);
this.scene.add(ambientLight);
var hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 1);
hemiLight.position.set(0, 500, 0);
this.scene.add(hemiLight);
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
this.stats = Stats();
document.body.appendChild(this.stats.dom)
this.render();
}
render() {
requestAnimationFrame(() => {
this.render();
this.stats.update();
});
// save the original camera properties
const currentRenderTarget = this.renderer.getRenderTarget();
const currentXrEnabled = this.renderer.xr.enabled;
const currentShadowAutoUpdate = this.renderer.shadowMap.autoUpdate;
this.renderer.xr.enabled = false; // Avoid camera modification
this.renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows
this.objects.forEach((object) => {
if(object instanceof Portal){
object.update(this.renderer, this.camera, this.scene);
}else {
object.update();
}
});
// restore the original rendering properties
this.renderer.xr.enabled = currentXrEnabled;
this.renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
this.renderer.setRenderTarget( currentRenderTarget );
this.renderer.render(this.scene, this.camera);
}
// addMesh(mesh){
// this.scene.add(mesh);
// }
add(mesh) {
if (Array.isArray(mesh)){
for(var index in mesh){
// if(mesh[index] instanceof Portal){
// mesh[index].getMesh().forEach(this.addMesh());
// }
this.objects.push(mesh[index]);
this.scene.add( mesh[index].getMesh() );
}
}
else{
this.objects.push(mesh);
this.scene.add(mesh.getMesh());
}
}
}
let app = new Application();
let objs = [
new Cube({ width: 4, height: 5, depth: 10 }, {x:5, y:4, z:-2}),
new Cube({ width: 5, height: 10, depth: 10 }, {x:-5, y:-4, z:-2}),
new Skybox({width:2000, height:2000, depth:2000},{x:0, y:300, z:0}),
new Plane({width:100, depth:100},{x:0, y:-10, z:0}, -Math.PI/2),
new Portal({width:10, height: 10}, {x:0,y:0,z:0}, {x:10,y:10, z:10},{x:0,y:Math.PI/2,z:0}, {x:0,y:Math.PI/2,z:0}),
];
app.add(objs);
And this is my error:
Uncaught TypeError: Cannot read properties of undefined (reading 'center')
at Sphere.copy (three.module.js:5433:28)
at Frustum.intersectsObject (three.module.js:12432:13)
at projectObject (three.module.js:27139:45)
at projectObject (three.module.js:27184:4)
at projectObject (three.module.js:27184:4)
at WebGLRenderer.render (three.module.js:26976:3)
at Portal.renderPortal (main.js:75:18)
at Portal.update (main.js:81:14)
at main.js:150:24
at Array.forEach (<anonymous>)
Thanks for any help in advance.