@@ -56,10 +56,13 @@ // Use to rotate selected points about a vector line var selection_rotation_axis = null; var rotation_center = origin.slice(0); +var zoom_center = origin.slice(0); + +var selected_points_start_loc = []; @@ -86,12 +89,13 @@ "Move wasd, qe\n" + "Copy Space\n" + "Delete x\n" + "\n" + "Click the red dot to create a point\n" + - "Drag between two points to connect them" + - "Spam a motion key to increase speed\n"; + "Spam a motion key to increase speed\n" + + "Drag between points to connect them\n"; + var msg = helpmsg; var view_transform = @@ -138,10 +142,14 @@ var FILL_COLOR = "rgba(0, 0, 0, 0.9)"; var LINE_WIDTH = 1; +function getKeyState(code){ + if(!key_state[code]) return 0; + return key_state[code].state; } + function addKeyListener(keycode, func){ if(!key_state[keycode]) key_state[keycode] = {}; @@ -297,11 +305,11 @@ var pt = points[selected_points[i]]; var newpt = addPoint(pt); new_selection[i] = newpt; } - //if(key_state[16] && key_state[16].state){ //shift + space copies lines as well. + //if(getKeyState(16)){ //shift + space copies lines as well. // copy lines as well for(var i = 0; i < lines.length; ++i){ var line = lines[i]; if(!line) continue; @@ -364,11 +372,11 @@ highlight_object = addPoint(origin); // create a new point at the origin var alreadySelected = false; // only set for shift clicks - if(key_state[16] && key_state[16].state){ // shift key is pressed. + if(getKeyState(16)){ // shift key is pressed. for(var i = 0; i < selected_points.length; ++i){ if(selected_points[i] == highlight_object){ selected_points.splice(i, 1); // deselect point alreadySelected = true; @@ -376,18 +384,18 @@ else{ selected_points.length = 0;} if(!alreadySelected && highlight_object < points.length) selected_points.push(highlight_object); } - else if(!key_state[16] || !key_state[16].state) + else if(!getKeyState(16)) selected_points.length = 0; } else if(lasts && mouse_dragging ){ // drag actions // connect selected points to highlight point with lines - if(selected_points.length && (!key_state[16] || !key_state[16].state)){ // TODO right now this really only works for drawing a single line, + if(selected_points.length && (!getKeyState(16))){ // TODO right now this really only works for drawing a single line, if(highlight_object !== null && highlight_object < point_projections.length){ if(highlight_object == -1) highlight_object = addPoint(origin); for(var i = 0; i < selected_points.length; ++i){ @@ -405,11 +413,11 @@ var maxy = Math.max(mouse_loc[1], last_mouse_down[1]); var selected_point_map = {}; - if(!key_state[16] || !key_state[16].state){ + if(!getKeyState(16)){ selected_points.length = 0; selected_lines.length = 0; } else{ for(var i = 0; i < selected_points.length; ++i){ selected_point_map[selected_points[i]] = i; }} @@ -430,11 +438,35 @@ // right click addKeyListener(1002, function(e, s, lasts){ if(s == 0){ delta_horizontal_angle = 0; - delta_vertical_angle = 0; }}); + delta_vertical_angle = 0; } + + else if(getKeyState(16)){ // use default as rotation center + rotation_center = origin.slice(0); } + + else if(highlight_object > 0){ // use highlighted points for rotation center. + if(highlight_object < points.length){ + rotation_center = points[highlight_object].slice(0); } + + else{ + var line = lines[highlight_object]; + var pointa = points[line[0]]; + var pointb = points[line[1]]; + rotation_center = vector_midpoint(pointa, pointb); + selection_rotation_axis = vector_minus(pointa, pointb); + if(vector_dot(selection_rotation_axis, view_transform[2]) < 0){ + vector_scale(-1, selection_rotation_axis, selection_rotation_axis); }}} // axis should be pointing vertical, horizontal motions along the screen will dictate motion angle. + + else if(selected_points.length){ //find average of selected points for rotation center + var rotation_center = [0,0,0]; + for(var i = 0; i < selected_points.length; ++i){ + vector_add(rotation_center, selected_points[i], rotation_center); } + var l = selected_points.length; + rotation_center = [rotation_center[0]/l, rotation_center[1]/l, rotation_center[2]/l]; + }}); function writeMsg(canvas, msg){ var lines = msg.split("\n"); var ctx = canvas.getContext("2d"); @@ -749,12 +781,12 @@ else{ document.body.style.cursor = "crosshair"; } if(mouse_dragging){ - if(selected_points.length && (!key_state[16] || !key_state[16].state)){ // if shift is held, we are selecting more points. - if(mouse_loc && key_state[1000] && key_state[1000].state){ + if(selected_points.length && !getKeyState(16)){ // if shift is held, we are selecting more points. + if(mouse_loc && getKeyState(1000)){ ctx.beginPath(); var pt = point_projections[selected_points[0]]; if(pt){ ctx.moveTo(mouse_loc[0], mouse_loc[1]); ctx.lineTo(pt[0], pt[1]); } @@ -761,11 +793,11 @@ ctx.stroke(); }} else if(mouse_loc && last_mouse_down){ - if(key_state[1000] && key_state[1000].state){ // select points inside square + if(getKeyState(1000)){ // select points inside square var minx = Math.min(mouse_loc[0], last_mouse_down[0]); var maxx = Math.max(mouse_loc[0], last_mouse_down[0]); var miny = Math.min(mouse_loc[1], last_mouse_down[1]); var maxy = Math.max(mouse_loc[1], last_mouse_down[1]); ctx.beginPath(); @@ -832,11 +864,11 @@ if(dist2 > MIN_DRAG_DIST * MIN_DRAG_DIST){ mouse_dragging = true; }} - if(key_state[1002] && key_state[1002].state && last_mouse_down){ + if(getKeyState(1002) && last_mouse_down){ delta_horizontal_angle = getRotationAngle(x - last_mouse_down[0], w, max_angle_delta/frame_rate, 0); delta_vertical_angle = -getRotationAngle(y - last_mouse_down[1], h, max_angle_delta/frame_rate, 0); } var min_point_dist2 = LINE_HIGHLIGHT_DIST * LINE_HIGHLIGHT_DIST; @@ -891,11 +923,11 @@ // function animateLoop(){ - if(selected_points.length){ // move selection if exists + if(selected_points.length && !getKeyState(1002)){ // move selection if exists for(var i = 0; i < selected_points.length; ++i){ var pt = points[selected_points[i]]; vector_add(pt, delta_position, pt); }} else{