From 648ee61ae84216d0236e0dbc211addc13b2cfa3a Mon Sep 17 00:00:00 2001 From: Kris Kowal Date: Fri, 6 Jul 2012 11:52:06 -0700 Subject: Expand tabs --- js/helper-classes/3D/draw-utils.js | 2092 ++++++++++++++++++------------------ 1 file changed, 1046 insertions(+), 1046 deletions(-) (limited to 'js/helper-classes/3D/draw-utils.js') diff --git a/js/helper-classes/3D/draw-utils.js b/js/helper-classes/3D/draw-utils.js index 235b381e..6f4c287d 100755 --- a/js/helper-classes/3D/draw-utils.js +++ b/js/helper-classes/3D/draw-utils.js @@ -42,104 +42,104 @@ var StageLine = require("js/helper-classes/3D/StageLine").StageLine; var DrawUtils = exports.DrawUtils = Montage.create(Component, { - /////////////////////////////////////////////////////////////////////// - // Instance variables - /////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////// + // Instance variables + /////////////////////////////////////////////////////////////////////// viewUtils: { value: null, writable: true }, snapManager: { value: null }, ElementPlanes : { value: null, writable: true }, - // the drawing surface (a canvas) - _drawingSurfaceElt : { value: null, writable: true }, - _drawingContext : { value: null, writable: true }, + // the drawing surface (a canvas) + _drawingSurfaceElt : { value: null, writable: true }, + _drawingContext : { value: null, writable: true }, - // color to draw the lines - _lineColor : { value: "black", writable: true}, + // color to draw the lines + _lineColor : { value: "black", writable: true}, - // define a stack for quickly setting graphics states and restoring them - _stateArray : { value: [], writable: true }, + // define a stack for quickly setting graphics states and restoring them + _stateArray : { value: [], writable: true }, - // save references to the grid lines for quick redraw - _gridLineArray : {value: [], writable: true }, + // save references to the grid lines for quick redraw + _gridLineArray : {value: [], writable: true }, - // state for moveTo, lineTo - _curPt : { value: null, writable: true }, - _curVis : { value: null, writable: true }, + // state for moveTo, lineTo + _curPt : { value: null, writable: true }, + _curVis : { value: null, writable: true }, - // the element that defines the coordinate system for the displayed lines - _sourceSpaceElt : { value: null, writable: true }, + // the element that defines the coordinate system for the displayed lines + _sourceSpaceElt : { value: null, writable: true }, - // maintain a list of objects to hide against - _eltArray : {value: [], writable: true }, + // maintain a list of objects to hide against + _eltArray : {value: [], writable: true }, - // maintain a list of the planes to test against - _planesArray : {value: [], writable: true }, + // maintain a list of the planes to test against + _planesArray : {value: [], writable: true }, - // the working plane. - // a grid may be drawn aligned with this working plane - _workingPlane : { value: null, writable: true }, + // the working plane. + // a grid may be drawn aligned with this working plane + _workingPlane : { value: null, writable: true }, - // save some parameters about the grid. - // these parameters are set when the grid is drawn - _gridHorizontalSpacing : {value: 50, writable: true }, - _gridVerticalSpacing : {value: 50, writable: true }, - _gridHorizontalLineCount : {value:10, writable: true }, - _gridVerticalLineCount : {value:0, writable: true }, - _gridOrigin : {value: null, writable: true }, + // save some parameters about the grid. + // these parameters are set when the grid is drawn + _gridHorizontalSpacing : {value: 50, writable: true }, + _gridVerticalSpacing : {value: 50, writable: true }, + _gridHorizontalLineCount : {value:10, writable: true }, + _gridVerticalLineCount : {value:0, writable: true }, + _gridOrigin : {value: null, writable: true }, - drawXY : {value: false, writable: true }, - drawXZ : {value: false, writable: true }, - drawYZ : {value: false, writable: true }, + drawXY : {value: false, writable: true }, + drawXZ : {value: false, writable: true }, + drawYZ : {value: false, writable: true }, - drawElementN : {value: false, writable: true }, + drawElementN : {value: false, writable: true }, - _selectionCtr : {value: null, writable: true }, + _selectionCtr : {value: null, writable: true }, // Properties that require element planes to be updated - _updatePlaneProps : {value: ["matrix", "left", "top", "width", "height"], writable: false }, - _recalculateScrollOffsets : { value: false }, + _updatePlaneProps : {value: ["matrix", "left", "top", "width", "height"], writable: false }, + _recalculateScrollOffsets : { value: false }, - /////////////////////////////////////////////////////////////////////// - // Property accessors - /////////////////////////////////////////////////////////////////////// - setDrawingSurfaceElement : { value: function( s ) { this._drawingSurfaceElt = s; if (s) this._drawingContext = s.getContext("2d"); }}, - getDrawingSurfaceElement : { value: function() { return this._drawingSurfaceElt; }}, + /////////////////////////////////////////////////////////////////////// + // Property accessors + /////////////////////////////////////////////////////////////////////// + setDrawingSurfaceElement : { value: function( s ) { this._drawingSurfaceElt = s; if (s) this._drawingContext = s.getContext("2d"); }}, + getDrawingSurfaceElement : { value: function() { return this._drawingSurfaceElt; }}, - getDrawingContext : { value: function() { return this._drawingContext; }}, + getDrawingContext : { value: function() { return this._drawingContext; }}, - setSourceSpaceElement : { value: function(ss) { this._sourceSpaceElt = ss; }}, - getSourceSpaceElement : { value: function() { return this._sourceSpaceElt; }}, + setSourceSpaceElement : { value: function(ss) { this._sourceSpaceElt = ss; }}, + getSourceSpaceElement : { value: function() { return this._sourceSpaceElt; }}, - getWorkingPlane : { value: function() { return this._workingPlane; }}, - setWorkingPlane : { value: function (wp) { this._workingPlane = wp; }}, + getWorkingPlane : { value: function() { return this._workingPlane; }}, + setWorkingPlane : { value: function (wp) { this._workingPlane = wp; }}, - getGridHorizontalSpacing : { value: function() { return this._gridHorizontalSpacing; }}, - getGridVerticalSpacing : { value: function() { return this._gridVerticalSpacing; }}, - getGridHorizontalLineCount : { value: function() { return this._gridHorizontalLineCount; }}, - getGridVerticalLineCount : { value: function() { return this._gridVerticalLineCount; }}, - getGridOrigin : { value: function() { return this._gridOrigin.slice(0); }}, + getGridHorizontalSpacing : { value: function() { return this._gridHorizontalSpacing; }}, + getGridVerticalSpacing : { value: function() { return this._gridVerticalSpacing; }}, + getGridHorizontalLineCount : { value: function() { return this._gridHorizontalLineCount; }}, + getGridVerticalLineCount : { value: function() { return this._gridVerticalLineCount; }}, + getGridOrigin : { value: function() { return this._gridOrigin.slice(0); }}, - isDrawingGrid : { value: function() { return this.drawXY || this.drawYZ || this.drawXZ; }}, - isDrawingElementNormal : { value: function() { return this.drawElementN }}, + isDrawingGrid : { value: function() { return this.drawXY || this.drawYZ || this.drawXZ; }}, + isDrawingElementNormal : { value: function() { return this.drawElementN }}, - getLineColor : { value: function() { return this._lineColor; }}, - setLineColor : { value: function( color ) { this._lineColor = color; }}, + getLineColor : { value: function() { return this._lineColor; }}, + setLineColor : { value: function( color ) { this._lineColor = color; }}, - getLineWidth : { value: function() { return this._drawingContext.lineWidth; }}, - setLineWidth : { value: function( w ) { this._drawingContext.lineWidth = w; }}, + getLineWidth : { value: function() { return this._drawingContext.lineWidth; }}, + setLineWidth : { value: function( w ) { this._drawingContext.lineWidth = w; }}, - initialize: { - value: function() { - this._gridOrigin = [0,0]; // 2D plane space point + initialize: { + value: function() { + this._gridOrigin = [0,0]; // 2D plane space point this.eventManager.addEventListener("elementAdded", this, false); this.eventManager.addEventListener("elementsRemoved", this, false); this.eventManager.addEventListener("elementChange", this, false); this.eventManager.addEventListener("elementChanging", this, false); this.eventManager.addEventListener("elementReplaced", this, false); - } - }, + } + }, initializeFromDocument:{ value:function(adjustScrollOffsets, useStageValues){ @@ -364,502 +364,502 @@ var DrawUtils = exports.DrawUtils = Montage.create(Component, { } }, - /////////////////////////////////////////////////////////////////////// - // Methods - /////////////////////////////////////////////////////////////////////// - - addElement: { - value: function( elt ) { - // check if we already know about this object - var n = this._eltArray.length; - for (var i=0; i 3) pt.pop(); - - var z = pt[2]; - var n = this._planesArray.length; - var vis = 0; - for (var i=0; i plane.getZMax()) continue; - - // test for containment in the polygon bounds - var contain = MathUtils.boundaryContainsPoint( plane.getBoundaryPoints(), pt, plane.isBackFacing() ); - if (contain == MathUtils.OUTSIDE) continue; - if (contain == MathUtils.ON) continue; - - // shoot a ray from the point in the +Z direction to get the z value of the plane - var vec = [0,0,1]; - var planeEq = plane.getPlaneEq(); - var ptOnPlane = MathUtils.vecIntersectPlane( pt, vec, planeEq ); - if (ptOnPlane) - { - // in keeping with the convention that a point "on" a face is outside the element, - // check that case. - //if (MathUtils.fpCmp(pt[2], ptOnPlane[2]) == 0) continue; - - // if the point is behind the plane, increase the visibility - if (MathUtils.fpCmp(pt[2],ptOnPlane[2]) <= 0) vis++; - } - } - - return vis; - } - }, - - moveTo : { - value: function( pt ) { - if (this._sourceSpaceElt) - pt = this.viewUtils.localToGlobal( pt, this._sourceSpaceElt ); - - this._curPt = pt.slice(0); - this._curVis = this.getVisibilityAtPoint( pt ); - } - }, - - lineTo : - { - value: function( pt ) - { - if (this._sourceSpaceElt) - pt = this.viewUtils.localToGlobal( pt, this._sourceSpaceElt ); - - var line = Object.create(StageLine, {}); - line.setPoints( this._curPt, pt ); - line.setVisibility( this._curVis ); - - // find all the plane intersections - this.getLineIntersections( line ); - - // draw the line - this._curVis = this.drawIntersectedLine( line, this._drawingContext ); - this._curPt = pt.slice(0); - } - }, - - - drawLine : - { - value: function( pt0, pt1 ) - { - if (this._drawingContext) - { - // transform the points from local object space to world space - if (this._sourceSpaceElt) - { - pt0 = this.viewUtils.localToGlobal( pt0, this._sourceSpaceElt ); - pt1 = this.viewUtils.localToGlobal( pt1, this._sourceSpaceElt ); - } - - // create the line structure - var line = Object.create(StageLine, {}); - line.setPoints( pt0, pt1 ); - - // find all the plane intersections - this.getLineIntersections( line ); - - // get the starting visibility - var vis = this.getVisibilityAtPoint( pt0 ); - line.setVisibility( vis ); - - // draw the line - this._curVis = this.drawIntersectedLine( line, this._drawingContext ); - } - } - }, - - drawIntersectedLine : - { - value: function( line ) - { - this._drawingContext.strokeStyle = this._lineColor; - this._drawingContext.beginPath(); - - // get the 2 enpoints of the line - var pt0 = line.getPoint0(), - pt1 = line.getPoint1(); - - // find the visibility at the start point - var vis = line.getVisibility(); - if (vis == 0) - { - this._drawingContext.strokeStyle = this._lineColor; - this._drawingContext.beginPath(); - this._drawingContext.moveTo( pt0[0], pt0[1] ); - } - - // go through each intersection - var n = line.getIntersectionCount(); - var t = 0.0; - var iRec = line.getIntersectionList(); - for (var i=0; i 3) pt.pop(); + + var z = pt[2]; + var n = this._planesArray.length; + var vis = 0; + for (var i=0; i plane.getZMax()) continue; + + // test for containment in the polygon bounds + var contain = MathUtils.boundaryContainsPoint( plane.getBoundaryPoints(), pt, plane.isBackFacing() ); + if (contain == MathUtils.OUTSIDE) continue; + if (contain == MathUtils.ON) continue; + + // shoot a ray from the point in the +Z direction to get the z value of the plane + var vec = [0,0,1]; + var planeEq = plane.getPlaneEq(); + var ptOnPlane = MathUtils.vecIntersectPlane( pt, vec, planeEq ); + if (ptOnPlane) + { + // in keeping with the convention that a point "on" a face is outside the element, + // check that case. + //if (MathUtils.fpCmp(pt[2], ptOnPlane[2]) == 0) continue; + + // if the point is behind the plane, increase the visibility + if (MathUtils.fpCmp(pt[2],ptOnPlane[2]) <= 0) vis++; + } + } + + return vis; + } + }, + + moveTo : { + value: function( pt ) { + if (this._sourceSpaceElt) + pt = this.viewUtils.localToGlobal( pt, this._sourceSpaceElt ); + + this._curPt = pt.slice(0); + this._curVis = this.getVisibilityAtPoint( pt ); + } + }, + + lineTo : + { + value: function( pt ) + { + if (this._sourceSpaceElt) + pt = this.viewUtils.localToGlobal( pt, this._sourceSpaceElt ); + + var line = Object.create(StageLine, {}); + line.setPoints( this._curPt, pt ); + line.setVisibility( this._curVis ); + + // find all the plane intersections + this.getLineIntersections( line ); + + // draw the line + this._curVis = this.drawIntersectedLine( line, this._drawingContext ); + this._curPt = pt.slice(0); + } + }, + + + drawLine : + { + value: function( pt0, pt1 ) + { + if (this._drawingContext) + { + // transform the points from local object space to world space + if (this._sourceSpaceElt) + { + pt0 = this.viewUtils.localToGlobal( pt0, this._sourceSpaceElt ); + pt1 = this.viewUtils.localToGlobal( pt1, this._sourceSpaceElt ); + } + + // create the line structure + var line = Object.create(StageLine, {}); + line.setPoints( pt0, pt1 ); + + // find all the plane intersections + this.getLineIntersections( line ); + + // get the starting visibility + var vis = this.getVisibilityAtPoint( pt0 ); + line.setVisibility( vis ); + + // draw the line + this._curVis = this.drawIntersectedLine( line, this._drawingContext ); + } + } + }, + + drawIntersectedLine : + { + value: function( line ) + { + this._drawingContext.strokeStyle = this._lineColor; + this._drawingContext.beginPath(); + + // get the 2 enpoints of the line + var pt0 = line.getPoint0(), + pt1 = line.getPoint1(); + + // find the visibility at the start point + var vis = line.getVisibility(); + if (vis == 0) + { + this._drawingContext.strokeStyle = this._lineColor; + this._drawingContext.beginPath(); + this._drawingContext.moveTo( pt0[0], pt0[1] ); + } + + // go through each intersection + var n = line.getIntersectionCount(); + var t = 0.0; + var iRec = line.getIntersectionList(); + for (var i=0; i maxPt[0]) maxPt[0] = x; - - if (y < minPt[1]) minPt[1] = y; - if (y > maxPt[1]) maxPt[1] = y; - - if (z < minPt[2]) minPt[2] = z; - if (z > maxPt[2]) maxPt[2] = z; - } - } - } - - // restore the root ID - this.viewUtils.setRootElement (saveRoot ); - - context.beginPath(); - - var x0 = minPt[0], y0 = minPt[1], z0 = minPt[2], - x1 = maxPt[0], y1 = maxPt[1], z1 = maxPt[2]; - - this._selectionCtr = [x0, y0, z0]; - this._selectionCtr[0] += (x1-x0)/2; - this._selectionCtr[1] += (y1-y0)/2; - this._selectionCtr[2] += (z1-z0)/2; - - // get the 8 corners of the parallelpiped in world space - var wc = new Array(); // wc == world cube - wc.push( this.viewUtils.localToGlobal2( [x0,y0,z1], ssMat ) ); - wc.push( this.viewUtils.localToGlobal2( [x0,y1,z1], ssMat ) ); - wc.push( this.viewUtils.localToGlobal2( [x1,y1,z1], ssMat ) ); - wc.push( this.viewUtils.localToGlobal2( [x1,y0,z1], ssMat ) ); - wc.push( this.viewUtils.localToGlobal2( [x0,y0,z0], ssMat ) ); - wc.push( this.viewUtils.localToGlobal2( [x0,y1,z0], ssMat ) ); - wc.push( this.viewUtils.localToGlobal2( [x1,y1,z0], ssMat ) ); - wc.push( this.viewUtils.localToGlobal2( [x1,y0,z0], ssMat ) ); - - // determine the signs of the normals of the faces relative to the view direction. - var front = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[2],wc[1]), vecUtils.vecSubtract(3,wc[0],wc[1]))[2] ), - right = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[6],wc[2]), vecUtils.vecSubtract(3,wc[3],wc[2]))[2] ), - back = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[5],wc[6]), vecUtils.vecSubtract(3,wc[7],wc[6]))[2] ), - left = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[1],wc[5]), vecUtils.vecSubtract(3,wc[4],wc[5]))[2] ), - top = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[3],wc[0]), vecUtils.vecSubtract(3,wc[4],wc[0]))[2] ), - bottom = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[5],wc[1]), vecUtils.vecSubtract(3,wc[2],wc[1]))[2] ); - - // draw the side faces - var p; - - //context.strokeStyle = ((front > 0) || (right > 0)) ? dark : light; context.beginPath(); - if ((front > 0) || (right > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x1, y0, z1], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x1, y1, z1], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - - //context.strokeStyle = ((right > 0) || (back > 0)) ? dark : light; context.beginPath(); - if ((right > 0) || (back > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x1, y0, z0], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x1, y1, z0], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - - //context.strokeStyle = ((back > 0) || (left > 0)) ? dark : light; context.beginPath(); - if ((back > 0) || (left > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x0, y0, z0], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x0, y1, z0], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - - //context.strokeStyle = ((left > 0) || (front > 0)) ? dark : light; context.beginPath(); - if ((left > 0) || (front > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x0, y0, z1], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x0, y1, z1], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - - // draw the top and bottom faces - //context.strokeStyle = ((front > 0) || (top > 0)) ? dark : light; context.beginPath(); - if ((front > 0) || (top > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x0, y0, z1], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x1, y0, z1], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - - //context.strokeStyle = ((top > 0) || (back > 0)) ? dark : light; context.beginPath(); - if ((top > 0) || (back > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x0, y0, z0], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x1, y0, z0], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - - //context.strokeStyle = ((back > 0) || (bottom > 0)) ? dark : light; context.beginPath(); - if ((back > 0) || (bottom > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x0, y1, z0], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x1, y1, z0], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - - //context.strokeStyle = ((bottom > 0) || (front > 0)) ? dark : light; context.beginPath(); - if ((bottom > 0) || (front > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x0, y1, z1], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x1, y1, z1], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - - // and the remaining lines - varying Z - if ((top > 0) || (right > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x1, y0, z0], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x1, y0, z1], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - - //context.strokeStyle = ((right > 0) || (bottom > 0)) ? dark : light; context.beginPath(); - if ((right > 0) || (bottom > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x1, y1, z0], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x1, y1, z1], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - - //context.strokeStyle = ((bottom > 0) || (left > 0)) ? dark : light; context.beginPath(); - if ((bottom > 0) || (left > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x0, y1, z0], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x0, y1, z1], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - - //context.strokeStyle = ((left > 0) || (top > 0)) ? dark : light; context.beginPath(); - if ((left > 0) || (top > 0)) { - context.beginPath(); - p = this.viewUtils.localToGlobal2( [x0, y0, z0], ssMat ); context.moveTo( p[0], p[1] ); - p = this.viewUtils.localToGlobal2( [x0, y0, z1], ssMat ); context.lineTo( p[0], p[1] ); - context.closePath(); context.stroke(); - } - } - } - } - }, - - - drawElementNormal: - { - value: function( elt ) - { - if (!this.isDrawingElementNormal()) return; - - // set the element to be the viewport object - temporarily - this.viewUtils.pushViewportObj( elt ); - - // save the source space object and set to the target object - var saveSource = this._sourceSpaceElt; - this._sourceSpaceElt = elt; - - // temporarily set the line color - var saveColor = this._lineColor; - this._lineColor = "blue"; - - var base = this.viewUtils.getCenterOfProjection(); - base[2] = 1; // Z - make it just off the plane to avoid numerical issues - var zAxis = base.slice(0); - zAxis[2] += 50; - this.moveTo( base ); - this.lineTo( zAxis ); - - // draw the arrowhead - var headWidth = 6; - var head = MathUtils.interpolateLine3D( base, zAxis, 0.7 ); - var p0 = head.slice(0); p0[1] += headWidth; this.drawLine( zAxis, p0 ); - var p1 = head.slice(0); p1[0] += headWidth; this.drawLine( zAxis, p1 ); - var p2 = head.slice(0); p2[1] -= headWidth; this.drawLine( zAxis, p2 ); - var p3 = head.slice(0); p3[0] -= headWidth; this.drawLine( zAxis, p3 ); - - this.moveTo( p0 ); - this.lineTo( p1 ); - this.lineTo( p2 ); - this.lineTo( p3 ); - this.lineTo( p0 ); - - // restore the state - this.viewUtils.popViewportObj(); - this._lineColor = saveColor; - this._sourceSpaceElt = saveSource; - } - }, + if (len === 1) + { + // single selection case + //console.log( "single selection" ); + + elt = eltArray[0]; + + this.viewUtils.pushViewportObj( elt ); + + // get the element bounds in world space + bounds3D = this.viewUtils.getElementViewBounds3D( elt ); + for (j=0; j<4; j++) { + bounds3D[j] = this.viewUtils.localToGlobal( bounds3D[j], elt ); + } + + // draw it + context.beginPath(); + //VV + context.strokeStyle = "#46a1ff"; + context.lineWidth = 2.0; + + context.moveTo( bounds3D[3][0] , bounds3D[3][1] ); + for (var v=0; v<4; v++) { + context.lineTo( bounds3D[v][0] , bounds3D[v][1] ); + } + context.closePath(); + context.stroke(); + + this._selectionCtr = MathUtils.getCenterFromBounds(3, bounds3D); +// console.log("selection center, single elt case - ", this._selectionCtr); + + this.viewUtils.popViewportObj(); + } + else + { + // get the plane from the first element to compare against the other elements + var dot; + var flat = true; + var plane = this.viewUtils.getUnprojectedElementPlane( eltArray[0] ); + for (i=1; i maxPt[0]) maxPt[0] = x; + + if (y < minPt[1]) minPt[1] = y; + if (y > maxPt[1]) maxPt[1] = y; + + if (z < minPt[2]) minPt[2] = z; + if (z > maxPt[2]) maxPt[2] = z; + } + } + } + + // restore the root ID + this.viewUtils.setRootElement (saveRoot ); + + context.beginPath(); + + var x0 = minPt[0], y0 = minPt[1], z0 = minPt[2], + x1 = maxPt[0], y1 = maxPt[1], z1 = maxPt[2]; + + this._selectionCtr = [x0, y0, z0]; + this._selectionCtr[0] += (x1-x0)/2; + this._selectionCtr[1] += (y1-y0)/2; + this._selectionCtr[2] += (z1-z0)/2; + + // get the 8 corners of the parallelpiped in world space + var wc = new Array(); // wc == world cube + wc.push( this.viewUtils.localToGlobal2( [x0,y0,z1], ssMat ) ); + wc.push( this.viewUtils.localToGlobal2( [x0,y1,z1], ssMat ) ); + wc.push( this.viewUtils.localToGlobal2( [x1,y1,z1], ssMat ) ); + wc.push( this.viewUtils.localToGlobal2( [x1,y0,z1], ssMat ) ); + wc.push( this.viewUtils.localToGlobal2( [x0,y0,z0], ssMat ) ); + wc.push( this.viewUtils.localToGlobal2( [x0,y1,z0], ssMat ) ); + wc.push( this.viewUtils.localToGlobal2( [x1,y1,z0], ssMat ) ); + wc.push( this.viewUtils.localToGlobal2( [x1,y0,z0], ssMat ) ); + + // determine the signs of the normals of the faces relative to the view direction. + var front = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[2],wc[1]), vecUtils.vecSubtract(3,wc[0],wc[1]))[2] ), + right = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[6],wc[2]), vecUtils.vecSubtract(3,wc[3],wc[2]))[2] ), + back = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[5],wc[6]), vecUtils.vecSubtract(3,wc[7],wc[6]))[2] ), + left = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[1],wc[5]), vecUtils.vecSubtract(3,wc[4],wc[5]))[2] ), + top = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[3],wc[0]), vecUtils.vecSubtract(3,wc[4],wc[0]))[2] ), + bottom = -MathUtils.fpSign( vecUtils.vecCross(3, vecUtils.vecSubtract(3,wc[5],wc[1]), vecUtils.vecSubtract(3,wc[2],wc[1]))[2] ); + + // draw the side faces + var p; + + //context.strokeStyle = ((front > 0) || (right > 0)) ? dark : light; context.beginPath(); + if ((front > 0) || (right > 0)) { + context.beginPath(); + p = this.viewUtils.localToGlobal2( [x1, y0, z1], ssMat ); context.moveTo( p[0], p[1] ); + p = this.viewUtils.localToGlobal2( [x1, y1, z1], ssMat ); context.lineTo( p[0], p[1] ); + context.closePath(); context.stroke(); + } + + //context.strokeStyle = ((right > 0) || (back > 0)) ? dark : light; context.beginPath(); + if ((right > 0) || (back > 0)) { + context.beginPath(); + p = this.viewUtils.localToGlobal2( [x1, y0, z0], ssMat ); context.moveTo( p[0], p[1] ); + p = this.viewUtils.localToGlobal2( [x1, y1, z0], ssMat ); context.lineTo( p[0], p[1] ); + context.closePath(); context.stroke(); + } + + //context.strokeStyle = ((back > 0) || (left > 0)) ? dark : light; context.beginPath(); + if ((back > 0) || (left > 0)) { + context.beginPath(); + p = this.viewUtils.localToGlobal2( [x0, y0, z0], ssMat ); context.moveTo( p[0], p[1] ); + p = this.viewUtils.localToGlobal2( [x0, y1, z0], ssMat ); context.lineTo( p[0], p[1] ); + context.closePath(); context.stroke(); + } + + //context.strokeStyle = ((left > 0) || (front > 0)) ? dark : light; context.beginPath(); + if ((left > 0) || (front > 0)) { + context.beginPath(); + p = this.viewUtils.localToGlobal2( [x0, y0, z1], ssMat ); context.moveTo( p[0], p[1] ); + p = this.viewUtils.localToGlobal2( [x0, y1, z1], ssMat ); context.lineTo( p[0], p[1] ); +