Ok long struggle…
I have this script on my camera to make the view expand in both vertical and horizontal while preserving a given aspect which is not always 1:1. It works! the script is made from reading this post: Issue with non square aspect ratio and resizing - #2 by yaustar - Thanks to @Mal_Duffin and @yaustar
CameraFrameWithinAspectRatio.attributes.add('minAspectRatio', { type: 'number' });
CameraFrameWithinAspectRatio.prototype.initialize = function () {
var self = this;
var onWindowResize = function () {
self._checkAspectRatio();
};
this._checkAspectRatio();
window.addEventListener('resize', onWindowResize, false);
// this.app.graphicsDevice.on('resizecanvas', onWindowResize);
var requiredAspectRatio = this.minAspectRatio;
pc.Mat4.prototype.setPerspective = function (fov, aspect, znear, zfar, fovIsHorizontal) {
var xmax, ymax;
if (!fovIsHorizontal) {
ymax = znear * Math.tan(fov * Math.PI / 360);
xmax = ymax * aspect;
}
else {
xmax = znear * Math.tan(fov * Math.PI / 360);
xmax *= requiredAspectRatio;
ymax = xmax / aspect;
}
return this.setFrustum(-xmax, xmax, -ymax, ymax, znear, zfar);
};
};
CameraFrameWithinAspectRatio.prototype._checkAspectRatio = function () {
this.entity.camera.horizontalFov = this.app.graphicsDevice.width / this.app.graphicsDevice.height < this.minAspectRatio;
};
Now my issue is that raycasting doesn’t work right. It is the combination of setPerspective and setting fovHorizontal true, that leads the raycasting being far off in the sides of the screen.
When ever the screen is wider than my desired 1.6 aspect ratio raycasting works great. Below the 1.6 (narrower screen) raycasting is off.
My raycasting code is attached to the root and look like this:
ClickObject.prototype.mouseDown = function (e) {
console.log(e)
this.doRaycast(e.x, e.y);
};
ClickObject.prototype.touchStart = function (e) {
// Only perform the raycast if there is one finger on the screen
if (e.touches.length === 1) {
this.doRaycast(e.touches[0].x, e.touches[0].y);
}
e.event.preventDefault();
};
ClickObject.prototype.doRaycast = function (screenX, screenY) {
if (this.active) {
// The pc.Vec3 to raycast from (the position of the camera)
var from = this.camera.getPosition();
// The pc.Vec3 to raycast to (the click position projected onto the camera's far clip plane)
var to = this.camera.camera.screenToWorld(screenX, screenY, this.camera.camera.farClip);
// Raycast between the two points and return the closest hit result
var result = this.app.systems.rigidbody.raycastFirst(from, to);
// If there was a hit, store the entity
if (result) {
var hitEntity = result.entity;
window.postMessage({
type: "CAMERA_CHANGE", value: {
id: hitEntity.name
}
}, "*")
}
}
};
Any ideas on what I’ve missed?