JavaFx 3D文件导入

3d文件转换工具Jar下载地址 :jfx3dimporter

package com.tdmodel;

import java.io.IOException;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;

/**
 *
 * @author zhuqing
 */
public class Import3dModel extends Application {

    private final Rotate cameraXRotate = new Rotate(-20, 0, 0, 0, Rotate.X_AXIS);
    private final Rotate cameraYRotate = new Rotate(-20, 0, 0, 0, Rotate.Y_AXIS);
    private final Translate cameraPosition = new Translate(0, 0, -20);

    private double scaleFactor = 1;

    private double dragStartX, dragStartY, dragStartRotateX, dragStartRotateY;

    @Override
    public void start(Stage primaryStage) throws IOException {

        BorderPane borderPane = new BorderPane();

        borderPane.setCenter(load3DModel());

        Scene scene = new Scene(borderPane, 800, 600);
        initMouseDrag(scene);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * 导入3d模型
     *
     * @return
     * @throws IOException
     */
    private Group load3DModel() throws IOException {

        /**
         * 创建摄像头
         */
        PerspectiveCamera camera = new PerspectiveCamera(true);
        camera.getTransforms().addAll(cameraXRotate, cameraYRotate, cameraPosition);

        /**
         * 导入3d模型
         */
        Group groupRoot = Importer3D.load("C:\\Users\\zhuqing.BJGOODWILL\\Documents\\NetBeansProjects\\3dModel\\src\\resources\\hands.3DS");
        groupRoot.getChildren().add(camera);

        /**
         * 创建SubScene
         */
        SubScene subScene = new SubScene(groupRoot, 800, 600, true, SceneAntialiasing.BALANCED);
        subScene.setCamera(camera);
        Group group = new Group();
        group.getChildren().add(subScene);

        return group;
    }

    private void initMouseDrag(Scene scene) {
        /**
         * 鼠标事件
         */
        scene.addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {

                if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
                    dragStartX = event.getSceneX();
                    dragStartY = event.getSceneY();
                    dragStartRotateX = cameraXRotate.getAngle();
                    dragStartRotateY = cameraYRotate.getAngle();
                } else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
                    double xDelta = event.getSceneX() - dragStartX;
                    double yDelta = event.getSceneY() - dragStartY;
                    cameraXRotate.setAngle(dragStartRotateX - (yDelta * 0.3));
                    cameraYRotate.setAngle(dragStartRotateY + (xDelta * 0.3));
                }

            }
        });

        /**
         * 滚轮滚动数据
         */
        scene.setOnScroll(new EventHandler<ScrollEvent>() {
            @Override
            public void handle(ScrollEvent event) {
                double z = cameraPosition.getZ() - (event.getDeltaY() * 0.1 * scaleFactor);
                z = Math.min(z, 0);
                cameraPosition.setZ(z);
            }
        });

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

package com.tdmodel;

import com.interactivemesh.jfx.importer.ModelImporter;
import com.interactivemesh.jfx.importer.stl.StlMeshImporter;
import com.interactivemesh.jfx.importer.tds.TdsModelImporter;
import com.interactivemesh.jfx.importer.x3d.X3dModelImporter;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.MeshView;
import javafx.scene.shape.TriangleMesh;

import java.io.IOException;

/**
 *3d模型导入工具
 */
public final class Importer3D {

    /**
     * 导入3d模型文件
     * @param fileUrl
     */
    public static Group load(final String fileUrl) throws IOException {

        final int dot = fileUrl.lastIndexOf('.');
        if (dot <= 0) {
            throw new IOException("Unknown 3D file format, url missing extension [" + fileUrl + "]");
        }
        final String extension = fileUrl.substring(dot + 1, fileUrl.length()).toLowerCase();

        switch (extension) {
            case "3ds":
                ModelImporter tdsImporter = new TdsModelImporter();
                tdsImporter.read(fileUrl);
                final Node[] tdsMesh = (Node[]) tdsImporter.getImport();
                tdsImporter.getNamedMaterials();
                return new Group(tdsMesh);
            case "stl":
                StlMeshImporter stlImporter = new StlMeshImporter();
                stlImporter.read(fileUrl);
                TriangleMesh cylinderHeadMesh = stlImporter.getImport();
                stlImporter.close();
                MeshView cylinderHeadMeshView = new MeshView();
                cylinderHeadMeshView.setMaterial(new PhongMaterial(Color.GRAY));
                cylinderHeadMeshView.setMesh(cylinderHeadMesh);
                stlImporter.close();
                return new Group(cylinderHeadMeshView);
            case "x3d":

                X3dModelImporter x3dModel = new X3dModelImporter();
                x3dModel.read(fileUrl);
                
                final Node[] x3dMesh = x3dModel.getImport();
                x3dModel.close();
                return new Group(x3dMesh);

            default:
                throw new IOException("Unsupported 3D file format [" + extension + "]");
        }
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • [cp]“ 可以不光芒万丈,但不能停止自己发光 ” ​​​[/cp]
    chde我阅读 140评论 0 0
  • 在所有困难前 必须先有耐心 时光总会匆匆而过 而心却需要沉淀 对的错的 热闹的安静的 有的人在承担 有的人尝试 却...
    天籁村阅读 296评论 0 0
  • 一场酣梦,梦一生 庄周化蝶,蝶成庄 情迷蝶意,蒙双眼 酒香远闻,已成醉 醉生梦死,孰是非 西下光辉,红似天 双色景...
    21e87e7c9a8c阅读 185评论 0 1
  • 每周二、周四下午八九节课都有第二课堂活动(兴趣小组),赶上运动会在即,体育场上都是锻炼的人。今天,体育委员邵威组织...
    白骨精的优雅阅读 231评论 0 3