@react-vertex/orbit-camera
Version:
Orbit Camera and Controls for React Vertex
173 lines (159 loc) • 4.94 kB
JavaScript
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import { vec3, vec4, mat4 } from 'gl-matrix';
import throttle from 'lodash.throttle';
export var OrbitCamera = /*#__PURE__*/function () {
function OrbitCamera(fov, aspect) {
var near = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var far = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1000;
_classCallCheck(this, OrbitCamera);
this.projection = void 0;
this.view = void 0;
this.matrix = void 0;
this.position = vec3.create();
this.up = vec3.create();
this.right = vec3.create();
this.normal = vec3.create();
this.userRotate = true;
this.userRotateX = true;
this.userRotateY = true;
this.userDolly = true;
this.rotX = 0;
this.rotY = 0;
this.steps = 0;
this.listeners = [];
this.matrix = mat4.create();
this.view = mat4.create();
mat4.invert(this.view, this.matrix);
var radians = fov * Math.PI / 180.0;
this.projection = mat4.create();
mat4.perspective(this.projection, radians, aspect, near, far);
}
_createClass(OrbitCamera, [{
key: "setProjection",
value: function setProjection(fov, aspect) {
var near = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var far = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1000;
var radians = fov * Math.PI / 180.0;
mat4.perspective(this.projection, radians, aspect, near, far);
}
}, {
key: "dolly",
value: function dolly(delta) {
if (this.userDolly) {
var next = vec3.create();
var step = delta - this.steps;
next[0] = this.position[0];
next[1] = this.position[1];
next[2] = this.position[2] - step;
this.steps = delta;
this.setPosition(next);
}
}
}, {
key: "setPosition",
value: function setPosition(position) {
this.position[0] = position[0] || 0;
this.position[1] = position[1] || 0;
this.position[2] = position[2] || 0;
this.update();
}
}, {
key: "upRightNormal",
value: function upRightNormal() {
var up = vec4.create();
vec4.set(up, 0, 1, 0, 0);
vec4.transformMat4(up, up, this.matrix);
vec3.copy(this.up, up);
var right = vec4.create();
vec4.set(right, 1, 0, 0, 0);
vec4.transformMat4(right, right, this.matrix);
vec3.copy(this.right, right);
var normal = vec4.create();
vec4.set(normal, 0, 0, 1, 0);
vec4.transformMat4(normal, normal, this.matrix);
vec3.copy(this.normal, normal);
}
}, {
key: "setRotationX",
value: function setRotationX(rotX) {
this.rotX = rotX;
if (this.rotX > 360 || this.rotX < -360) {
this.rotX = this.rotX % 360;
}
this.update();
}
}, {
key: "incRotationX",
value: function incRotationX(rotX) {
if (this.userRotate && this.userRotateX) {
this.rotX += rotX;
if (this.rotX > 360 || this.rotX < -360) {
this.rotX = this.rotX % 360;
}
this.update();
}
}
}, {
key: "setRotationY",
value: function setRotationY(rotY) {
this.rotY = rotY;
if (this.rotY > 360 || this.rotY < -360) {
this.rotY = this.rotY % 360;
}
this.update();
}
}, {
key: "incRotationY",
value: function incRotationY(rotY) {
if (this.userRotate && this.userRotateY) {
this.rotY += rotY;
if (this.rotY > 360 || this.rotY < -360) {
this.rotY = this.rotY % 360;
}
this.update();
}
}
}, {
key: "addListener",
value: function addListener(func) {
var wait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 16;
var listener = throttle(func, wait);
this.listeners.push({
listener: listener,
id: func
});
}
}, {
key: "removeListener",
value: function removeListener(func) {
var index = this.listeners.findIndex(function (d) {
return d.id === func;
});
if (index !== -1) {
this.listeners.splice(index, 1);
}
}
}, {
key: "exportView",
value: function exportView() {
return mat4.clone(this.view);
}
}, {
key: "update",
value: function update() {
var _this = this;
mat4.identity(this.matrix);
mat4.rotateX(this.matrix, this.matrix, this.rotX * Math.PI / 180);
mat4.rotateY(this.matrix, this.matrix, this.rotY * Math.PI / 180);
mat4.translate(this.matrix, this.matrix, this.position);
mat4.invert(this.view, this.matrix);
this.upRightNormal();
this.listeners.forEach(function (item) {
item.listener(_this);
});
}
}]);
return OrbitCamera;
}();
//# sourceMappingURL=OrbitCamera.js.map