@needle-tools/engine
Version:
Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.
83 lines • 4.08 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { Matrix4, Object3D, Quaternion, Vector3 } from "three";
import { serializable } from "../../engine/engine_serialization.js";
import { lookAtObject } from "../../engine/engine_three_utils.js";
import { ActionBuilder, BehaviorModel, TriggerBuilder, USDVec3 } from "../../engine-components/export/usdz/extensions/behavior/BehavioursBuilder.js";
import { USDObject } from "../../engine-components/export/usdz/ThreeUSDZExporter.js";
import { Behaviour } from "../Component.js";
/**
* LookAt behaviour makes the object look at a target object or the camera.
* It can also invert the forward direction and keep the up direction.
*/
export class LookAt extends Behaviour {
/**
* The target object to look at. If not set, the main camera will be used.
*/
target;
/**
* Inverts the forward direction.
*/
invertForward = false;
/**
* Keep the up direction.
*/
keepUpDirection = true;
/**
* Copy the target rotation.
*/
copyTargetRotation = false;
static flipYQuat = new Quaternion().setFromAxisAngle(new Vector3(0, 1, 0), Math.PI);
/** @internal */
onBeforeRender() {
let target = this.target;
if (!target)
target = this.context.mainCamera;
if (!target)
return;
let copyTargetRotation = this.copyTargetRotation;
// Disable copy target rotation during VR/AR session: https://linear.app/needle/issue/NE-5634
if (this.context.isInVR || this.context.isInPassThrough) {
copyTargetRotation = false;
}
lookAtObject(this.gameObject, target, this.keepUpDirection, copyTargetRotation);
if (this.invertForward)
this.gameObject.quaternion.multiply(LookAt.flipYQuat);
}
/** @internal */
createBehaviours(ext, model, _context) {
if (model.uuid === this.gameObject.uuid) {
let alignmentTarget = model;
// not entirely sure why we need to do this - looks like LookAt with up vector doesn't work properly in
// QuickLook, so we need to introduce an empty parent and rotate the model by 90° around Y
if (this.keepUpDirection) {
const parent = USDObject.createEmptyParent(model);
alignmentTarget = parent;
// rotate by 90° - counter-rotation on the parent makes sure
// that without Preliminary Behaviours it still looks right
const flip = this.invertForward ? -1 : 1;
parent.setMatrix(parent.getMatrix().multiply(new Matrix4().makeRotationZ(Math.PI / 2 * flip)));
model.setMatrix(model.getMatrix().multiply(new Matrix4().makeRotationZ(-Math.PI / 2 * flip)));
}
const lookAt = new BehaviorModel("lookat " + this.name, TriggerBuilder.sceneStartTrigger(), ActionBuilder.lookAtCameraAction(alignmentTarget, undefined, this.invertForward ? USDVec3.back : USDVec3.forward, this.keepUpDirection ? USDVec3.up : USDVec3.zero));
ext.addBehavior(lookAt);
}
}
}
__decorate([
serializable(Object3D)
], LookAt.prototype, "target", void 0);
__decorate([
serializable()
], LookAt.prototype, "invertForward", void 0);
__decorate([
serializable()
], LookAt.prototype, "keepUpDirection", void 0);
__decorate([
serializable()
], LookAt.prototype, "copyTargetRotation", void 0);
//# sourceMappingURL=LookAt.js.map