使用AxisHelper帮助理解View and Data API中的坐标系统

大家使用View and Data API做三维模型开发,必然首先要理解View and Data API的坐标系统,即XYZ三个轴向分别是怎么定义的。Three.js里面提供了一个AxisHelper,但如果你直接运用的话,你会发现在viewer中并不显示,并且控制台中会有这样的错误信息:"Only THREE.Mesh can be rendered by the Firefly renderer. Use THREE.Mesh to draw lines."  原因是因为View and Data API采用的是Three.js上定制的render,有些three.js中可以使用的功能在viewer中并不能用。所以我重写了一个这样的AxisHelper,希望对你有帮助。

 

使用非常简单,只需要加载这个扩展即可。建议在GEOMETRY_LOADED_EVENT事件中加载:

// It is recommended to load the extension when geometry is loaded
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, 
   function(){

   viewer.loadExtension('Autodesk.ADN.Viewing.Extension.AxisHelper');

   });

下面是截图,你可以看到红线是X轴,绿线是Y轴,蓝线是Z轴。请注意和右上角的view cube的对应关系。

Screen Shot 2015-12-10 at 2.38.34 PM

下面是这个扩展的源代码,不过最好到 github 上下载,因为我可能会时不时的做更新,github上的才是最新的。

///////////////////////////////////////////////////////////////////////////////
AutodeskNamespace("Autodesk.ADN.Viewing.Extension");

Autodesk.ADN.Viewing.Extension.AxisHelper = function (viewer, options) {

    Autodesk.Viewing.Extension.call(this, viewer, options);

    var _self = this;

    var _axisLines = [];

    _self.load = function () {

        console.log('Autodesk.ADN.Viewing.Extension.AxisHelper loaded');

        addAixsHelper();

        //workaround
        //have to call this to show up the axis
        viewer.restoreState(viewer.getState());

        return true;
    };



    _self.unload = function () {

        removeAixsHelper();

        console.log('Autodesk.ADN.Viewing.Extension.AxisHelper unloaded');
        return true;
    };


    var addAixsHelper = function() {

        _axisLines = [];

        //get bounding box of the model
        var boundingBox = viewer.model.getBoundingBox();
        var maxpt = boundingBox.max;
        var minpt = boundingBox.min;
     
        var xdiff =    maxpt.x - minpt.x;
        var ydiff =    maxpt.y - minpt.y;
        var zdiff =    maxpt.z - minpt.z;

        //make the size is bigger than the max bounding box 
        //so that it is visible 
        var size = Math.max(xdiff,ydiff,zdiff) * 1.2; 
        //console.log('axix size :' + size);


        // x-axis is red
        var material_X_Axis = new THREE.LineBasicMaterial({
            color: 0xff0000,  //red 
            linewidth: 2
        });
        viewer.impl.matman().addMaterial('material_X_Axis',material_X_Axis,true);
        //draw the x-axix line
        var xLine = drawLine(
            {x : 0, y : 0, z : 0} ,
            {x : size, y : 0, z : 0} , 
            material_X_Axis);
       
        _axisLines.push(xLine);


        // y-axis is green
        var material_Y_Axis = new THREE.LineBasicMaterial({
            color: 0x00ff00,  //green 
            linewidth: 2
        });
        viewer.impl.matman().addMaterial('material_Y_Axis',material_Y_Axis,true);
        //draw the y-axix line
        var yLine = drawLine(
            {x : 0, y : 0, z : 0} ,
            {x : 0, y : size, z : 0} , 
            material_Y_Axis);
        
        _axisLines.push(yLine);


        // z-axis is blue
        var material_Z_Axis = new THREE.LineBasicMaterial({
            color: 0x0000ff,  //blue 
            linewidth: 2
        });
        viewer.impl.matman().addMaterial('material_Z_Axis',material_Z_Axis,true);
        //draw the z-axix line
        var zLine = drawLine(
            {x : 0, y : 0, z : 0} ,
            {x : 0, y : 0, z : size} , 
            material_Z_Axis);
      
        _axisLines.push(zLine);


    }


    var drawLine = function(start, end, material) {

            var geometry = new THREE.Geometry();

            geometry.vertices.push(new THREE.Vector3(
                start.x, start.y, start.z));

            geometry.vertices.push(new THREE.Vector3(
                end.x, end.y, end.z));

            var line = new THREE.Line(geometry, material);

            viewer.impl.scene.add(line);
            //refresh viewer
            viewer.impl.invalidate(true);

            return line;
    }

    var removeAixsHelper = function() {

        _axisLines = [];

        _axisLines.forEach(function(line){

            viewer.impl.scene.remove(line);
        });

        //remove materials
        delete viewer.impl.matman().materials.material_X_Axis;
        delete viewer.impl.matman().materials.material_Y_Axis;
        delete viewer.impl.matman().materials.material_Z_Axis;

        
    }


};

Autodesk.ADN.Viewing.Extension.AxisHelper.prototype =
    Object.create(Autodesk.Viewing.Extension.prototype);

Autodesk.ADN.Viewing.Extension.AxisHelper.prototype.constructor =
    Autodesk.ADN.Viewing.Extension.AxisHelper;

Autodesk.Viewing.theExtensionManager.registerExtension(
    'Autodesk.ADN.Viewing.Extension.AxisHelper',
    Autodesk.ADN.Viewing.Extension.AxisHelper);

Hope it helps.


Related Posts Plugin for WordPress, Blogger...