Java3D讀取3DMax模型並實現鼠標拖拽、旋轉、滾輪縮放等功能


/**-------------------------------------------------代碼區--------------------------------------------------------**/

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

import com.sun.j3d.loaders.Scene;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.behaviors.mouse.*;
import com.sun.j3d.utils.pickfast.behaviors.PickRotateBehavior;
import com.sun.j3d.utils.pickfast.behaviors.PickTranslateBehavior;
import com.sun.j3d.utils.pickfast.behaviors.PickZoomBehavior;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.javax.media.j3d.*;
import com.sun.javax.vecmath.*;
import com.microcrowd.loader.java3d.max3ds.Loader3DS;
/**
* 3DMax文件加載測試
* @author luo
*
*/
public class M3DMax3dsfileLoader extends Applet {
  BranchGroup scenceBranchGroupRoot =null;
  BoundingSphere bounds=null;
  TransformGroup sceneTG=null;
  TransformGroup objTG=null;
  Transform3D t3d1 =null;
  TransformGroup tg1=null;
  BranchGroup loaderBG =null;


  public M3DMax3dsfileLoader(){
    this.setLayout(new BorderLayout());
    GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
    Canvas3D canvas = new Canvas3D(gc);
    this.add("Center",canvas);
    //this.addMouseWheelListener(this);
    BranchGroup scence = createScenceGraph(canvas);
    SimpleUniverse u = new SimpleUniverse(canvas);
    u.getViewingPlatform().setNominalViewingTransform();
    u.addBranchGraph(scence);
  }

  /**
  * 創建場景
  * @return
  */
  public BranchGroup createScenceGraph(Canvas3D canvas){
    //創建BranchGroup
    scenceBranchGroupRoot = new BranchGroup();
    //創建球形范圍、背景、光源
    bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0),100.0);
    sceneTG = new TransformGroup();
    sceneTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    scenceBranchGroupRoot.addChild(sceneTG);

    //定義鼠標旋轉功能
    MouseRotate mouserotate = new MouseRotate();
    mouserotate.setTransformGroup(sceneTG);
    scenceBranchGroupRoot.addChild(mouserotate);
    mouserotate.setSchedulingBounds(bounds);

    //定義鼠標縮放功能
    MouseWheelZoom mouseWheelZoom = new MouseWheelZoom();
    mouseWheelZoom.setTransformGroup(sceneTG);
    scenceBranchGroupRoot.addChild(mouseWheelZoom);
    mouseWheelZoom.setSchedulingBounds(bounds);

    //定義鼠標拖拽功能
    MouseTranslate mouseTranslate = new MouseTranslate();
    mouseTranslate.setTransformGroup(sceneTG);
    scenceBranchGroupRoot.addChild(mouseTranslate);
    mouseTranslate.setSchedulingBounds(bounds);

    //定義背景色
    Color3f bgColor = new Color3f(1.0f,1.0f,1.0f);
    Background bg = new Background(bgColor);
    bg.setApplicationBounds(bounds);
    scenceBranchGroupRoot.addChild(bg);

    //定義兩個平行光源的顏色及照射方向,一個環境光源的顏色
    Color3f light1Color = new Color3f(1.0f,1.0f,1.0f);
    Vector3f light1Direction = new Vector3f(4.0f,-7.0f,-12.0f);
    Color3f light2Color = new Color3f(1.0f,1.0f,1.0f);
    Vector3f light2Direction = new Vector3f(-6.0f,-2.0f,-1.0f);
    Color3f ambientColor = new Color3f(1.0f,1.0f,1.0f);

    //用前面定義的顏色定義環境光
    AmbientLight ambientLight = new AmbientLight(ambientColor);
    ambientLight.setInfluencingBounds(bounds);
    scenceBranchGroupRoot.addChild(ambientLight);

    //用前面定義的照射方向與顏色定義兩個平行光
    DirectionalLight light1 = new DirectionalLight(light1Color,light1Direction);
    light1.setInfluencingBounds(bounds);
    scenceBranchGroupRoot.addChild(light1);

    DirectionalLight light2 = new DirectionalLight(light2Color,light2Direction);
    light2.setInfluencingBounds(bounds);
    scenceBranchGroupRoot.addChild(light2);
    /**
    * TransformGroup特點:
    * 1.在三維空間中放置任何形體,燈光,聲音都要要到該對象。
    * 2.該對象用來定義一個通過設置,可以移動、旋轉和放大縮小的局部坐標系。
    * 3.該對象有兩個flags,其中ALLOW_TRANSFORM_WRITE用來將最新的數據(即坐標變化后的數據寫入到數據結構中),
    * 允許程序在運行的時候修改該節點上的場景。ALLOW_TRANSFORM_READ用來讀取位置變化前的數據,從而進行判斷和處理。
    * 允許程序在運行的時候讀取該節點上的場景。
    * 4.通過設置ALLOW_TRANSFORM_WRITE來使坐標系運動(此時在不要讀取值時使用,如讀取移動的距離,選旋轉的角度,
    * 縮放的比例等值。若要讀取這些值,則要再使用ALLOW_TRANSFORM_READ)
    * 5.要在程序中通過鼠標,移動、旋轉、比例放大所指定的局部坐標系,則需要同時設置ALLOW_TRANSFORM_WRITE和ALLOW_TRANSFORM_READ。
    * 6.Java虛擬機會為這兩個flags創建單獨的線程(或者進程)來負責接收場景的反饋,在控制場景,避免了用戶不必要的開銷。
    */
    objTG = new TransformGroup();
    sceneTG.addChild(objTG);

    //定義存放3DMax文件的TransformGroup
    tg1 = new TransformGroup();
    /**
    * Transform3D的特點
    * 1.表示所指定的坐標的坐標變換,如旋轉、放大縮小、平移等
    * 2.Quat4f(x,y,z,w)的參數介紹:x:x坐標 y:y坐標 z:z坐標 w:物體旋轉的角度 如:
    * Quat4f(0.0f,1.0f,0.0f,1.57f) 表示物體繞Y軸旋轉90度,當Y軸的只越大則旋轉的幅度越大。
    * 當x,y,z的值不為0時,其值的大小即表示轉動幅度的大小,值越大,表示向該方向轉動的幅度也越大。
    * 3.Transform3D有四個方法rotx(),roty(), rotz(),setTranslation().當這四個方法一起使用的時候,只有最后一個有作用。
    * 為了能夠讓rotx,roty, rotz都顯示出來,則可以使用setRotation(new Quat4())來代替,
    * 此時不論setTranslation()在setRotation(new Quat4())前還是后,都可以顯示出效果
    */
    t3d1 = new Transform3D();
    t3d1.setScale(0.005);//初始化大小

    t3d1.setTranslation(new Vector3f(0.0f,0.0f,-0.4f));
    tg1 = new TransformGroup(t3d1);

    //定義3dmax文件以及所有相關材質文件及所在目錄。
    String modelDir = "";
    String fileName = "car.3DS";
    loaderBG = new BranchGroup();
    try{
        Loader3DS modelLoader = new Loader3DS();
        Scene loaderScene = modelLoader.load(modelDir+fileName);
        if(loaderScene!=null){
            loaderBG = loaderScene.getSceneGroup();
        }
    }catch(Exception e){
        e.printStackTrace();
    }

    tg1.addChild(loaderBG);
    objTG.addChild(tg1);

    return scenceBranchGroupRoot;
  }

  public static void main(String[] args){
    new MainFrame(new M3DMax3dsfileLoader(), 900,720);
  }


}

 /**-------------------------------------------------代碼區 end--------------------------------------------------------**/

 運行效果:

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM