UNPKG

@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.

193 lines • 7.53 kB
import { Matrix4, Object3D, Vector3 } from "three"; import { TransformControlsGizmo } from "three/examples/jsm/controls/TransformControls.js"; import { addComponent, getComponent, getComponentInChildren, getComponentInParent, getComponents, getComponentsInChildren, getComponentsInParent, getOrAddComponent, removeComponent } from "../../engine/engine_components.js"; import { destroy, isActiveSelf, setActive } from "../../engine/engine_gameobject.js"; import { getTempQuaternion, getTempVector, getWorldPosition, getWorldQuaternion, getWorldRotation, getWorldScale, setWorldPosition, setWorldQuaternion, setWorldRotation, setWorldScale } from "../../engine/engine_three_utils.js"; import { NEEDLE_ENGINE_FEATURE_FLAGS } from "../engine_feature_flags.js"; import { markHierarchyDirty } from "../engine_mainloop_utils.js"; import { applyPrototypeExtensions, registerPrototypeExtensions } from "./ExtensionUtils.js"; /** * @internal * used to decorate cloned object3D objects with the same added components defined above **/ export function apply(object) { if (object && object.isObject3D === true) { applyPrototypeExtensions(object, Object3D); } } if (NEEDLE_ENGINE_FEATURE_FLAGS.experimentalSmartHierarchyUpdate) { const addFn = Object3D.prototype.add; Object3D.prototype.add = function (...args) { markHierarchyDirty(); return addFn.apply(this, args); }; const attachFn = Object3D.prototype.attach; Object3D.prototype.attach = function (...args) { markHierarchyDirty(); return attachFn.apply(this, args); }; const removeFn = Object3D.prototype.remove; Object3D.prototype.remove = function (...args) { markHierarchyDirty(); return removeFn.apply(this, args); }; } // #region Prototype Method Implementations Object3D.prototype["SetActive"] = function (active) { this.visible = active; }; // e.g. when called via a UnityEvent Object3D.prototype["setActive"] = function (active) { this.visible = active; }; Object3D.prototype["destroy"] = function () { destroy(this); }; Object3D.prototype["addComponent"] = function (comp, init) { return addComponent(this, comp, init); }; Object3D.prototype["addNewComponent"] = function (type, init) { return addComponent(this, type, init); }; Object3D.prototype["removeComponent"] = function (inst) { return removeComponent(this, inst); }; Object3D.prototype["getOrAddComponent"] = function (typeName, init) { return getOrAddComponent(this, typeName, init); }; Object3D.prototype["getComponent"] = function (type) { return getComponent(this, type); }; Object3D.prototype["getComponents"] = function (type, arr) { return getComponents(this, type, arr); }; Object3D.prototype["getComponentInChildren"] = function (type, includeInactive = false) { return getComponentInChildren(this, type, includeInactive); }; Object3D.prototype["getComponentsInChildren"] = function (type, arr) { return getComponentsInChildren(this, type, arr); }; Object3D.prototype["getComponentInParent"] = function (type, includeInactive = false) { return getComponentInParent(this, type, includeInactive); }; Object3D.prototype["getComponentsInParent"] = function (type, arr) { return getComponentsInParent(this, type, arr); }; // #region Prototype Property Implementations // this is a fix to allow gameObject active animation be applied to a three object if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "activeSelf")) { Object.defineProperty(Object3D.prototype, "activeSelf", { get: function () { return isActiveSelf(this); }, set: function (val) { setActive(this, val); } }); } if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "raycastAllowed")) { Object.defineProperty(Object3D.prototype, "raycastAllowed", { get: function () { return this.userData && this.userData.raycastAllowed !== false; }, set: function (val) { const self = this; if (!self.userData) self.userData = {}; self.userData.raycastAllowed = val; } }); } if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldPosition")) { Object.defineProperty(Object3D.prototype, "worldPosition", { get: function () { // TODO: would be great to remove this - just a workaround because the TransformControlsGizmo also defines this if (this instanceof TransformControlsGizmo) { return getWorldPosition(this["object"]); } return getWorldPosition(this); }, set: function (val) { setWorldPosition(this, val); } }); } if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldQuaternion")) { Object.defineProperty(Object3D.prototype, "worldQuaternion", { get: function () { if (this instanceof TransformControlsGizmo) { return getWorldQuaternion(this["object"]); } return getWorldQuaternion(this); }, set: function (val) { setWorldQuaternion(this, val); } }); } if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldRotation")) { Object.defineProperty(Object3D.prototype, "worldRotation", { get: function () { return getWorldRotation(this); }, set: function (val) { setWorldRotation(this, val); } }); } if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldScale")) { Object.defineProperty(Object3D.prototype, "worldScale", { get: function () { return getWorldScale(this); }, set: function (val) { setWorldScale(this, val); } }); } const tempMatrix = new Matrix4(); const zero = new Vector3(0, 0, 0); const up = new Vector3(0, 1, 0); if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldForward")) { Object.defineProperty(Object3D.prototype, "worldForward", { get: function () { return getTempVector().set(0, 0, 1).applyQuaternion(getWorldQuaternion(this)); }, set: function (v) { const quat = getTempQuaternion().setFromRotationMatrix(tempMatrix.lookAt(zero.set(0, 0, 0), v, up.set(0, 1, 0))); this.worldQuaternion = quat; } }); } if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldRight")) { Object.defineProperty(Object3D.prototype, "worldRight", { get: function () { return getTempVector().set(1, 0, 0).applyQuaternion(getWorldQuaternion(this)); }, }); } if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldUp")) { Object.defineProperty(Object3D.prototype, "worldUp", { get: function () { return getTempVector().set(0, 1, 0).applyQuaternion(getWorldQuaternion(this)); }, }); } if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "contains")) { Object.defineProperty(Object3D.prototype, "contains", { value: function (object) { if (!object) return false; if (this === object) return true; for (const child of this.children) { if (child.contains(object)) return true; } return false; } }); } // do this after adding the component extensions registerPrototypeExtensions(Object3D); //# sourceMappingURL=Object3D.js.map