使用AxisHelper幫助理解View and Data API中的座標系統

峻祁連發表於2015-12-10

大家使用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.

相關文章