React 3D Model Example

Demonstrates how to load a 3D model in React and show it in a SciChart3DSurface. The engine can load any 3D model, not just the car shown here.

Downloading the 3D model (~19 MB)… 0%

Fullscreen

Edit

 Edit

Docs

drawExample.ts

index.tsx

theme.ts

modelLoadProgress.ts

Copy to clipboard
Minimise
Fullscreen
1import {
2    BaseSceneEntity3D,
3    EMainLightMode,
4    ESceneEntityType,
5    MouseWheelZoomModifier3D,
6    NumericAxis3D,
7    OrbitModifier3D,
8    ResetCamera3DModifier,
9    SciChart3DSurface,
10    TSciChart3D,
11    Vector3,
12} from "scichart";
13import { appTheme } from "../../../theme";
14
15/**
16 * The model to load, named by its path inside the asset package. Nothing here is specific to a car -
17 * the SciChart 3D engine loads any model you cook into a package (glTF, OBJ, STL, STEP and more).
18 */
19const modelFileName = "AstonMartin/aston.glb.twi";
20
21/**
22 * The asset package holding the model. The engine appends ".web.pkg" and fetches the result, so this
23 * may be a bare name served from your site root, or an absolute URL as it is here.
24 */
25const modelPackage = "https://stagingdemo.scichart.com/fileshare/F1CarAssets";
26
27/**
28 * A thin {@link BaseSceneEntity3D} wrapper around the native model entity, so the loaded model can be
29 * added to the 3D scene via sciChart3DSurface.rootEntity.children.
30 */
31class ModelSceneEntity extends BaseSceneEntity3D<any> {
32    public readonly type = ESceneEntityType.SCRTSceneEntity;
33
34    constructor(webAssemblyContext: TSciChart3D) {
35        super(webAssemblyContext);
36        const nativeEntity = new webAssemblyContext.SCRTCADModelSceneEntity(modelFileName, modelPackage);
37        // Sizes the model to the 3D world. The package is downloaded in the background and the scene
38        // redraws itself once the model is ready.
39        nativeEntity.SetModelScale(0.1);
40        this.setNativeEntity(nativeEntity);
41    }
42
43    /**
44     * True once the package has been downloaded and the model is in the scene. The native entity only
45     * reports a node hierarchy once it has a model, so an empty hierarchy means "still loading".
46     */
47    public get isModelLoaded(): boolean {
48        try {
49            const hierarchyJson = this.nativeEntity.GetNodeHierarchyJson();
50            return hierarchyJson ? JSON.parse(hierarchyJson).nodes?.length > 0 : false;
51        } catch {
52            return false;
53        }
54    }
55}
56
57export const drawExample = async (rootElement: string | HTMLDivElement) => {
58    const { sciChart3DSurface, wasmContext } = await SciChart3DSurface.create(rootElement, {
59        theme: appTheme.SciChartJsTheme,
60        lighting: {
61            ambientLight: 0.25,
62            lightMode: EMainLightMode.GlobalSpace,
63            lightDirection: new Vector3(-1, -1, -1),
64        },
65        // Framed so the whole model is in view on startup. Double-click returns the camera here.
66        cameraOptions: {
67            position: new Vector3(24, 12, 24),
68            target: new Vector3(0, 1, 0),
69        },
70        // Leave only the floor plane, so the model is not boxed in by the axis cube
71        xyAxisPlane: { isVisible: false },
72        zyAxisPlane: { isVisible: false },
73    });
74
75    sciChart3DSurface.xAxis = new NumericAxis3D(wasmContext);
76    sciChart3DSurface.yAxis = new NumericAxis3D(wasmContext);
77    sciChart3DSurface.zAxis = new NumericAxis3D(wasmContext);
78
79    // A model is not a renderable series - it is a scene entity added to the root entity
80    const model = new ModelSceneEntity(wasmContext);
81    sciChart3DSurface.rootEntity.children.add(model);
82
83    // A large model can take a while to arrive, so the example shows a loader until it does. The entity
84    // has no load event, so poll it. The returned function stops waiting when the chart goes away.
85    const waitForModel = (onModelLoaded: () => void) => {
86        const intervalId = setInterval(() => {
87            if (!model.isModelLoaded) return;
88            clearInterval(intervalId);
89            // A cached package can arrive before the first render pass, so ask for a redraw once the
90            // model is in the scene. Without this the scene stays empty until something else redraws it.
91            sciChart3DSurface.invalidateElement();
92            onModelLoaded();
93        }, 200);
94        return () => clearInterval(intervalId);
95    };
96
97    sciChart3DSurface.chartModifiers.add(
98        new MouseWheelZoomModifier3D(),
99        new OrbitModifier3D(),
100        new ResetCamera3DModifier()
101    );
102
103    return { sciChartSurface: sciChart3DSurface, wasmContext, waitForModel };
104};
105

3D Model Example

This example loads a 3D model into a SciChart3DSurface. The model shown here is a racing car, but nothing in the code is specific to it: the SciChart 3D engine can load any 3D model, so the same few lines will show a CAD assembly, a scanned part, a machine, a building or a character.

How it works

  • A model is not a renderable series, it is a scene entity. A thin BaseSceneEntity3D wrapper holds the native model entity and is added to sciChart3DSurface.rootEntity.children.
  • The model is named by its path inside an asset package. The engine appends .web.pkg to the package name and fetches the result, so the package may be a bare name served from your site root, or an absolute URL as it is here.
  • The package downloads in the background, so the example shows a loader until the model is in the scene. The entity has no load event: it reports a node hierarchy only once it has a model, so polling that tells you when the model has arrived.
  • Call invalidateElement() at that point. A cached package can arrive before the first render pass, and without a redraw the scene would stay empty.
  • SetModelScale() sizes the model to the 3D world, and the camera is placed so the whole model is in view when the example opens.
  • Only the floor plane of the axis cube is drawn here, so the model is not boxed in by the X-Y and Z-Y planes.

Orbit with the left mouse button, zoom with the mouse wheel and double-click to reset the camera.

SciChart Ltd, 16 Beaufort Court, Admirals Way, Docklands, London, E14 9XL.