package collada2; import java.io.File; import java.util.HashMap; import java.util.Map; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import org.collada._2005._11.colladaschema.COLLADA; import org.collada._2005._11.colladaschema.LibraryVisualScenes; import org.collada._2005._11.colladaschema.Matrix; import org.collada._2005._11.colladaschema.Node; import org.collada._2005._11.colladaschema.VisualScene; import javafx.scene.Group; /** * Collada ver1.4.1を読み込むクラス * @author tomo * */ public class Dae141FileLoader { private static Map nodeMap = null; // 読み込んだDaeNodeのマップ /** * クラスのインスタンス化を防ぐ */ private Dae141FileLoader(){}; /** * daeファイルを指定して、ColladaDataを作成 * @param fileName * @return */ public static ColladaData load( String fileName ) { // 戻り値を作成 ColladaData data = new ColladaData(); COLLADA collada = null; // 変数を初期化 File f = new File( fileName ); Dae141FileLoader.nodeMap = new HashMap<>(); // ファイルから読み込み try { // 読込パッケージを決定 String packageName = "org.collada._2005._11.colladaschema"; // XMLパーサを作成 JAXBContext jc = JAXBContext.newInstance( packageName ); Unmarshaller unmarshaller = jc.createUnmarshaller(); // JAXBを利用して、ファイルからインスタンスを作成 collada = (COLLADA) unmarshaller.unmarshal( f ); } catch (JAXBException e) { e.printStackTrace(); } // タグの読込開始 // ルートタグであるColladaから読込開始 loadColladaTag( collada , data ); // 作成したColladaDataを返す return data; } /** * DAEファイルからメッシュを抽出する * @param collada * @return */ private static void loadColladaTag( final COLLADA collada , ColladaData data ) { // ルートノードを作成 Group root = new Group(); // 『library_○○』タグを処理(0回以上) for( Object o : collada.getLibraryAnimationsAndLibraryAnimationClipsAndLibraryCameras() ) { if ( o instanceof LibraryVisualScenes ) { // 子要素Library_visual_scenesを処理 LibraryVisualScenes libraryVisualScenes = (LibraryVisualScenes) o; // プロパティidを処理 // プロパティnameを処理 // 子要素Visual_sceneを処理(1以上) for( VisualScene visualScene : libraryVisualScenes.getVisualScenes() ) { // ルートノードを作成 DaeNode daeNodeRoot = new DaeNode(); // プロパティidを処理 // プロパティnameを処理 // 子要素assetを処理(0or1) // 子要素nodeを処理(1以上) for( Node nodeTag : visualScene.getNodes() ) { daeNodeRoot.getChildren().add( loadNodeTag( nodeTag ) ); } // 子要素evaluate_sceneを処理(0以上) // 子要素extraを処理(0以上) // ルートノードを登録 data.setDaeNodeRoot( daeNodeRoot ); // ノードマップを登録 data.getDaeNodeMap().putAll( nodeMap ); } // 子要素assetを処理(0or1) // 子要素extraを処理(0以上) } } } /** * ノードタグを読み込む * @param node * @return */ private static DaeNode loadNodeTag( Node nodeTag ) { // ノード情報保持クラスを作成 DaeNode daeNode = null; // TYPE=JOINTの場合はJointBoneクラスでインスタンス化 if( ( nodeTag.getType() != null ) && ( nodeTag.getType().value().equalsIgnoreCase( "JOINT" ) ) ) { daeNode = new JointBone(); } else { daeNode = new DaeNode(); } // プロパティidを処理 if( nodeTag.getId() != null ){ daeNode.setId( nodeTag.getId() ); } // プロパティnameを処理 if( nodeTag.getName() != null ){ daeNode.setName( nodeTag.getName() ); } // プロパティsidを処理 if( nodeTag.getSid() != null ){ daeNode.setSid( nodeTag.getSid() ); } // プロパティtypeを処理 if( nodeTag.getType() != null ){ daeNode.setType( nodeTag.getType().value() ); } // 子要素assetを処理(0or1) // 子要素を処理 for( Object o2 : nodeTag.getLookatsAndMatrixesAndRotates() ) { if( o2 instanceof Matrix ) { // 子要素matrixを処理(0以上) Matrix matrix = (Matrix) o2 ; // 値を取得 double[][] tmp = new double[4][4]; for( int y=0 ; y<4 ; y++ ) for( int x=0 ; x<4 ; x++ ) tmp[y][x] = matrix.getValues().get( 4 * y + x ); // ノードに値を設定 daeNode.setMatrix( tmp ); }else{ // 子要素lookatを処理(0以上) // 子要素rotateを処理(0以上) // 子要素scaleを処理(0以上) // 子要素skewを処理(0以上) // 子要素translateを処理(0以上) } } // 子要素instance_cameraを処理(0以上) // 子要素instance_controllerを処理(0以上) // 子要素instance_geometryを処理(0以上) // 子要素instance_lightを処理(0以上) // 子要素instance_nodeを処理(0以上) // 子要素extraを処理(0以上) // DaeNodeの登録 if( daeNode.getId() != null ){ nodeMap.put( daeNode.getId() , daeNode ); } // 子要素nodeを処理(0以上) for( Node childNodeTag : nodeTag.getNodes() ) { // NODEタイプの処理 DaeNode childDaeNode = loadNodeTag( childNodeTag ); // 子ノードとして登録 if( childDaeNode != null ) { daeNode.getChildren().add( childDaeNode ); childDaeNode.setParentTransform( daeNode.getGrobalTransforms() ); } } // ジョイントの場合のみインスタンスを返す return daeNode; } }