three.js - manipualte object hierarchies
by mmalex
HTML
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.js"></script>
<script src="http://mbnsay.com/rayys/assets/js/OrbitControls.js"></script>
<script src="http://rawgit.mbnsay.com/nmalex/three.js-helpers/master/RayysMouse.js"></script>
<script src="http://mbnsay.com/rayys/assets/js/clipper_unminified.js"></script>
CSS
body {
overflow: hidden;
padding: 0;
margin: 0;
}
JavaScript
class RayysMouseMove {
constructor(rayysMouse, controls) {
this.camera = rayysMouse.camera;
this.mouse = rayysMouse;
this.controls = controls || this.mouse.controls;
this.mouse.controls = undefined; // overtake mouse controls, if any defined
this.objects = [];
this.cb = {
onModeChanged: [],
onObjectEnter: [],
onObjectLeave: [],
onBeforeStart: [], //callbacks here may return false to prevent operation
onPreviewObjectMove: [], //callbacks here may return alternative position
onObjectMove: [],
onObjectReleased: [],
onVoidClick: []
};
this.raycaster = new THREE.Raycaster();
this.translationLimits = new THREE.Vector3();
this.translationPlane = new THREE.Plane(new THREE.Vector3(0, -1, 0), 0);
this.translationPlaneHelper = new THREE.PlaneHelper(this.translationPlane, 10, 0xff0000);
this.toggle("xz");
var handleMouseDown = function(pos) {
console.log(`Mouse down at: ${JSON.stringify(pos)}`);
this.raycaster.setFromCamera(pos, this.camera);
var intersects = this.raycaster.intersectObjects(this.objects, true);
if (intersects.length > 0) {
var canProceed = true;
// check with subscribers, if this object is movable in current context
for (let i = 0; i < this.cb.onBeforeStart.length; i++) {
if (this.cb.onBeforeStart[i](intersects[0].object, this) === false) {
canProceed = false;
}
}
if (!canProceed) return;
if (this.controls) {
this.controls.enablePan = false;
this.controls.enableRotate = false;
}
this.pickPoint = intersects[0].point;
let pickedObj = intersects[0].object
if (this.objects.indexOf(pickedObj) !== -1) {
this.pickedObj = pickedObj;
} else {
let pickedParent = pickedObj.parent;
while (pickedParent) {
if (this.objects.indexOf(pickedParent) !== -1) {
...