提交 e7621bfe 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #11359 from linev/fastsvg

Improve performance of SVGRenderer
......@@ -44,9 +44,9 @@ THREE.SVGRenderer = function () {
_viewMatrix = new THREE.Matrix4(),
_viewProjectionMatrix = new THREE.Matrix4(),
_svgPathPool = [], _svgLinePool = [], _svgRectPool = [],
_svgNode, _pathCount = 0, _lineCount = 0, _rectCount = 0,
_quality = 1;
_svgPathPool = [],
_svgNode, _pathCount = 0, _currPath, _currStyle,
_quality = 1, _precision = null;
this.domElement = _svg;
......@@ -104,11 +104,15 @@ THREE.SVGRenderer = function () {
};
this.setPrecision = function ( precision ) {
_precision = precision;
};
function removeChildNodes() {
_pathCount = 0;
_lineCount = 0;
_rectCount = 0;
while ( _svg.childNodes.length > 0 ) {
......@@ -118,10 +122,26 @@ THREE.SVGRenderer = function () {
}
function getSvgColor ( color, opacity ) {
var arg = Math.floor( color.r * 255 ) + ',' + Math.floor( color.g * 255 ) + ',' + Math.floor( color.b * 255 );
if ( opacity === undefined || opacity === 1 ) return 'rgb(' + arg + ')';
return 'rgba(' + arg + ',' + opacity + ')';
}
function convert ( c ) {
return _precision !== null ? c.toFixed(_precision) : c;
}
this.clear = function () {
removeChildNodes();
_svg.style.backgroundColor = 'rgba(' + Math.floor( _clearColor.r * 255 ) + ',' + Math.floor( _clearColor.g * 255 ) + ',' + Math.floor( _clearColor.b * 255 ) + ',' + _clearAlpha + ')';
_svg.style.backgroundColor = getSvgColor( _clearColor, _clearAlpha );
};
......@@ -139,7 +159,7 @@ THREE.SVGRenderer = function () {
if ( background && background.isColor ) {
removeChildNodes();
_svg.style.backgroundColor = 'rgb(' + Math.floor( background.r * 255 ) + ',' + Math.floor( background.g * 255 ) + ',' + Math.floor( background.b * 255 ) + ')';
_svg.style.backgroundColor = getSvgColor( background );
} else if ( this.autoClear === true ) {
......@@ -160,6 +180,7 @@ THREE.SVGRenderer = function () {
_normalViewMatrix.getNormalMatrix( camera.matrixWorldInverse );
calculateLights( _lights );
_currPath = _currStyle = ""; // reset accumulated path
for ( var e = 0, el = _elements.length; e < el; e ++ ) {
......@@ -220,6 +241,8 @@ THREE.SVGRenderer = function () {
}
flushPath(); // just to flush last svg:path
scene.traverseVisible( function ( object ) {
if ( object instanceof THREE.SVGObject ) {
......@@ -331,37 +354,28 @@ THREE.SVGRenderer = function () {
scaleY *= material.size;
}
_svgNode = getRectNode( _rectCount ++ );
_svgNode.setAttribute( 'x', v1.x - ( scaleX * 0.5 ) );
_svgNode.setAttribute( 'y', v1.y - ( scaleY * 0.5 ) );
_svgNode.setAttribute( 'width', scaleX );
_svgNode.setAttribute( 'height', scaleY );
var path = 'M' + convert( v1.x - scaleX * 0.5 ) + ',' + convert( v1.y - scaleY * 0.5 ) + 'h' + convert( scaleX ) + 'v' + convert( scaleY ) + 'h' + convert(-scaleX) + 'z';
var style = "";
if ( material.isSpriteMaterial || material.isPointsMaterial ) {
_svgNode.setAttribute( 'style', 'fill: ' + material.color.getStyle() );
style = 'fill:' + getSvgColor( material.color, material.opacity );
}
_svg.appendChild( _svgNode );
addPath( style, path );
}
function renderLine( v1, v2, element, material ) {
_svgNode = getLineNode( _lineCount ++ );
_svgNode.setAttribute( 'x1', v1.positionScreen.x );
_svgNode.setAttribute( 'y1', v1.positionScreen.y );
_svgNode.setAttribute( 'x2', v2.positionScreen.x );
_svgNode.setAttribute( 'y2', v2.positionScreen.y );
var path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y );
if ( material instanceof THREE.LineBasicMaterial ) {
_svgNode.setAttribute( 'style', 'fill: none; stroke: ' + material.color.getStyle() + '; stroke-width: ' + material.linewidth + '; stroke-opacity: ' + material.opacity + '; stroke-linecap: ' + material.linecap + '; stroke-linejoin: ' + material.linejoin );
var style = 'fill:none;stroke:' + getSvgColor( material.color, material.opacity ) + ';stroke-width:' + material.linewidth + ';stroke-linecap:' + material.linecap + ';stroke-linejoin:' + material.linejoin;
_svg.appendChild( _svgNode );
addPath( style, path );
}
......@@ -372,8 +386,8 @@ THREE.SVGRenderer = function () {
_this.info.render.vertices += 3;
_this.info.render.faces ++;
_svgNode = getPathNode( _pathCount ++ );
_svgNode.setAttribute( 'd', 'M ' + v1.positionScreen.x + ' ' + v1.positionScreen.y + ' L ' + v2.positionScreen.x + ' ' + v2.positionScreen.y + ' L ' + v3.positionScreen.x + ',' + v3.positionScreen.y + 'z' );
var path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y ) + 'L' + convert( v3.positionScreen.x ) + ',' + convert( v3.positionScreen.y ) + 'z';
var style = '';
if ( material instanceof THREE.MeshBasicMaterial ) {
......@@ -413,75 +427,66 @@ THREE.SVGRenderer = function () {
if ( material.wireframe ) {
_svgNode.setAttribute( 'style', 'fill: none; stroke: ' + _color.getStyle() + '; stroke-width: ' + material.wireframeLinewidth + '; stroke-opacity: ' + material.opacity + '; stroke-linecap: ' + material.wireframeLinecap + '; stroke-linejoin: ' + material.wireframeLinejoin );
style = 'fill:none;stroke:' + getSvgColor( _color, material.opacity ) + ';stroke-width:' + material.wireframeLinewidth + ';stroke-linecap:' + material.wireframeLinecap + ';stroke-linejoin:' + material.wireframeLinejoin;
} else {
_svgNode.setAttribute( 'style', 'fill: ' + _color.getStyle() + '; fill-opacity: ' + material.opacity );
style = 'fill:' + getSvgColor( _color, material.opacity );
}
_svg.appendChild( _svgNode );
addPath( style, path );
}
function getLineNode( id ) {
if ( _svgLinePool[ id ] == null ) {
function addPath ( style, path ) {
_svgLinePool[ id ] = document.createElementNS( 'http://www.w3.org/2000/svg', 'line' );
if ( _currStyle == style ) {
if ( _quality == 0 ) {
_currPath += path
_svgLinePool[ id ].setAttribute( 'shape-rendering', 'crispEdges' ); //optimizeSpeed
} else {
}
flushPath();
return _svgLinePool[ id ];
_currStyle = style;
_currPath = path;
}
return _svgLinePool[ id ];
}
function getPathNode( id ) {
if ( _svgPathPool[ id ] == null ) {
_svgPathPool[ id ] = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' );
function flushPath() {
if ( _quality == 0 ) {
_svgPathPool[ id ].setAttribute( 'shape-rendering', 'crispEdges' ); //optimizeSpeed
}
if ( _currPath ) {
return _svgPathPool[ id ];
_svgNode = getPathNode( _pathCount ++ );
_svgNode.setAttribute( 'd', _currPath );
_svgNode.setAttribute( 'style', _currStyle );
_svg.appendChild( _svgNode );
}
return _svgPathPool[ id ];
_currPath = _currStyle = "";
}
function getRectNode( id ) {
function getPathNode( id ) {
if ( _svgRectPool[ id ] == null ) {
if ( _svgPathPool[ id ] == null ) {
_svgRectPool[ id ] = document.createElementNS( 'http://www.w3.org/2000/svg', 'rect' );
_svgPathPool[ id ] = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' );
if ( _quality == 0 ) {
_svgRectPool[ id ].setAttribute( 'shape-rendering', 'crispEdges' ); //optimizeSpeed
_svgPathPool[ id ].setAttribute( 'shape-rendering', 'crispEdges' ); //optimizeSpeed
}
return _svgRectPool[ id ];
return _svgPathPool[ id ];
}
return _svgRectPool[ id ];
return _svgPathPool[ id ];
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册