/** * Created by aghassaei on 1/16/15. */ define(['underscore', 'backbone', 'three', 'appState', 'globals', 'lattice', 'orbitControls'], function(_, Backbone, THREE, appState, globals, lattice){ return Backbone.View.extend({ events: { "mousemove": "_mouseMoved", "mouseup": "_mouseUp", "mousedown": "_mouseDown", "mouseout": "_mouseOut" }, mouseIsDown: false,//store state of mouse click inside this el //intersections/object highlighting mouseProjection: new THREE.Raycaster(), currentIntersectedPart: null, el: "#threeContainer", controls: null, initialize: function(){ _.bindAll(this, "_mouseMoved", "_animate"); //bind events this.listenTo(appState, "change:deleteMode change:extrudeMode change:shift", this._setControlsEnabled); this.controls = new THREE.OrbitControls(this.model.camera, this.$el.get(0)); this.controls.addEventListener('change', this.model.render); this.$el.append(this.model.domElement);//render only once this.model.render(); // this._animate(); }, //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////CONTROLS///////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// _animate: function(){ // requestAnimationFrame(this._animate); // this.controls.update(); }, _setControlsEnabled: function(){ var state = appState.get("deleteMode") || appState.get("shift") || appState.get("extrudeMode"); this.controls.noRotate = state; }, //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////MOUSE EVENTS///////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// _mouseOut: function(){ if (globals.highlighter) globals.highlighter.setNothingHighlighted(); this._setNoPartIntersections(); }, _mouseUp: function(){ this.mouseIsDown = false; if (appState.get("currentTab") == "cam" && appState.get("manualSelectOrigin")){ var position = globals.highlighter.getHighlightedObjectPosition(); if (position){ require(['cam'], function(cam){ cam.set("originPosition", position); appState.set("manualSelectOrigin", false); }); return; } } if (this.currentIntersectedPart) this.currentIntersectedPart.removeFromCell(); else globals.highlighter.addRemoveVoxel(!appState.get("deleteMode")); }, _mouseDown: function(){ this.mouseIsDown = true; }, _mouseMoved: function(e){ if (!globals.highlighter) return;//highlighter not loaded yet if (!appState.get("highlightMode") && !(appState.get("manualSelectOrigin"))) return; if (this.mouseIsDown && !this.controls.noRotate) {//in the middle of a camera move globals.highlighter.setNothingHighlighted(); this._setNoPartIntersections(); return; } //make projection vector var vector = new THREE.Vector2(2*(e.pageX-this.$el.offset().left)/this.$el.width()-1, 1-2*(e.pageY-this.$el.offset().top)/this.$el.height()); this.mouseProjection.setFromCamera(vector, this.model.camera); var objsToIntersect = lattice.getUItarget().getHighlightableCells().concat(this.model.getBasePlane()); // if (globals.highlighter.isVisible()) objsToIntersect = objsToIntersect.concat(globals.highlighter.mesh); var intersections = this.mouseProjection.intersectObjects(objsToIntersect, false); if (intersections.length == 0) {//no intersections globals.highlighter.setNothingHighlighted(); this._setNoPartIntersections(); return; } if(intersections[0].object == globals.highlighter.mesh) return; globals.highlighter.highlight(intersections[0]); if (this.mouseIsDown) { if (appState.get("deleteMode")){ globals.highlighter.addRemoveVoxel(false); } else if (appState.get("shift")){ globals.highlighter.addRemoveVoxel(true); } } // if (appState.get("cellMode") == "part"){//additionally check for part intersections in part mode // var partIntersections = this.mouseProjection.intersectObjects(this.model.parts, false); // if (partIntersections.length == 0) { // this._setNoPartIntersections(); // return; // } // this._handlePartIntersections(partIntersections, intersections[0].distance); // } }, //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////INTERSECTIONS//////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// _setNoPartIntersections: function(){ if (this.currentIntersectedPart){ this.currentIntersectedPart.unhighlight(); this.currentIntersectedPart = null; this.model.render(); } }, _handlePartIntersections: function(intersections, distanceToNearestCell){ var part = intersections[0].object.myPart; if (globals.highlighter.isVisible() && intersections[0].distance > distanceToNearestCell){ this._setNoPartIntersections(); return; } globals.highlighter.hide(); if (part!= this.currentIntersectedPart){ if (this.currentIntersectedPart) this.currentIntersectedPart.unhighlight(); part.highlight(); this.currentIntersectedPart = part; this.model.render(); } } }); });