package collada2; import java.util.HashMap; import java.util.Map; import javafx.geometry.Point3D; import javafx.scene.Group; import javafx.scene.Node; import javafx.scene.paint.Color; import javafx.scene.paint.PhongMaterial; import javafx.scene.shape.Cylinder; import javafx.scene.shape.Sphere; import javafx.scene.transform.Rotate; import javafx.scene.transform.Translate; public class ColladaData { // ジョイント関係 Group jointsRootNode = new Group(); // DaeNode daeNodeRoot = null; // DaeNodeのルート Map daeNodeMap = new HashMap<>(); // DaeNodeのマップ /** * 画面に出力するジョイントイメージを作成する * @return */ public Node getJointsNode() { // ルートノードを作成 jointsRootNode = new Group(); // ジョイントノードを再帰的に探索し、 // ルートノードに登録していく getJointsNodeRecursive( jointsRootNode , daeNodeRoot ); return jointsRootNode; } /** * ジョイントを表示するかを設定する * @param flg */ public void setJointVisible( Boolean flg ) { jointsRootNode.setVisible( flg ); } /** * ジョイントを再帰的に探索し、描画ノードを登録していく * @param parent */ private void getJointsNodeRecursive( Group out , DaeNode parentNode ) { // 子ノードが存在しない場合処理終了確認(再帰の終了条件) if( ( parentNode == null ) || ( parentNode.getChildren().size() == 0 ) ){ return; } // ジョイントを追加する。 for( DaeNode node : parentNode.getChildren() ) { // ジョイントの場合は位置を示す球体を出力 if( node instanceof JointBone ) { // 球体を取得 Sphere sphere = node.getSphere(); sphere.setRadius( 0.05 ); // 色を指定 PhongMaterial material = new PhongMaterial(); material.setDiffuseColor( Color.RED ); sphere.setMaterial( material ); // 描写ノードとして登録 out.getChildren().add( sphere ); // 親がジョイントの場合は、親子のジョイント間を線でつないでボーンを表現する if( parentNode instanceof JointBone ) { // 親と子の座標を取得 Point3D coordParent = parentNode.getPoint3D(); Point3D coordChild = node.getPoint3D(); // 2点間の中点と距離を計算 Point3D centerPoint = coordParent.midpoint( coordChild ); double distance = coordParent.distance( coordChild ); // 回転軸を計算 // y軸と親子をつなぐ線に直角な線を外積を求めることで計算 Point3D rotateAxis = coordParent.subtract( coordChild ).crossProduct( 0.0 , 1.0 , 0.0 ); // 回転角を計算 double rotateAngle = coordParent.subtract( coordChild ).angle( 0.0 , 1.0 , 0.0 ); // 線分を作成 Cylinder line = new Cylinder( 0.025 , distance ); line.getTransforms().add( new Translate( centerPoint.getX() , centerPoint.getY() , centerPoint.getZ() ) ); line.getTransforms().add( new Rotate( - rotateAngle , rotateAxis ) ); // 色を設定 line.setMaterial( material ); out.getChildren().add( line ); } } // 下層を探索 getJointsNodeRecursive( out , node ); } } /* 以下単純なsetterとgetter */ public DaeNode getDaeNodeRoot() { return daeNodeRoot; } public void setDaeNodeRoot(DaeNode daeNodeRoot) { this.daeNodeRoot = daeNodeRoot; } public Map getDaeNodeMap() { return daeNodeMap; } }