Sure thing. It happens in onSceneReady
.
Just to reiterate – this code works when I import using
<script src="https://preview.babylonjs.com/babylon.max.js"></script>
<script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
<script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
<script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.js"></script>
<script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.js"></script>
but not when using the following npm modules.
"@babylonjs/core": "^5.34.0",
"@babylonjs/loaders": "^5.34.0",
"babylonjs": "^5.34.0",
import React, { Component } from "react";
import { withModule } from "react-hoc-di";
import BaseRenderer from "../renderer/Base3DRenderer";
import { EffectLayerSceneComponent } from '@babylonjs/core/Layers/effectLayerSceneComponent';
import { UniversalCamera } from '@babylonjs/core/Cameras/universalCamera'; // Must import this to enable gltf loading.
import { GLTFLoader } from '@babylonjs/loaders/glTF/2.0/glTFLoader'; // Must import this to enable gltf loading. // Must import this to enable gltf loading.
import { GLTFFileLoader } from '@babylonjs/loaders/glTF/glTFFileLoader'
import { SceneLoader } from "@babylonjs/core/Loading/sceneLoader";
import '@babylonjs/loaders';
import '@babylonjs/core/Helpers/sceneHelpers';
import '@babylonjs/core/Loading/loadingScreen';
// import { Ray } from '@babylonjs/core/Culling/ray';
import Base3DModule from "../module/Base3DModule";
class Base3DScene extends Component {
constructor(props) {
super(props);
this.module = props.module;
this.onSceneReady = this.onSceneReady.bind(this);
this.onPointerDown = this.onPointerDown.bind(this);
this.onPointerUp = this.onPointerUp.bind(this);
this.renderSubject = this.module.renderSubject;
this.sceneSubject = this.module.sceneSubject;
this.renderRequestStream = this.module.renderRequestStream;
this.scenePointerDownSubject = this.module.scenePointerDownSubject;
this.scenePointerUpSubject = this.module.scenePointerUpSubject;
this.sceneClickSubject = this.module.sceneClickSubject;
}
onPointerDown(evt, pickResult) {
this.pointerDownTime = Date.now();
this.renderRequestStream.on();
this.scenePointerDownSubject.next(pickResult);
}
onPointerUp(evt, pickResult) {
this.renderRequestStream.off();
this.renderRequestStream.lease(2000);
if (!this.pointerDownTime) {
return;
}
this.scenePointerUpSubject.next([evt, pickResult]);
if (this.camera) {
// console.log(`CAMERA POSITION: ${this.camera.position}`)
// console.log(`CAMERA RADIUS: ${this.camera.radius}`)
}
const offsetTimeMs = Date.now() - this.pointerDownTime;
if (offsetTimeMs < 300) {
this.sceneClickSubject.next([evt, pickResult]);
}
}
componentDidMount() {
BABYLON.GLTFFileLoader.IncrementalLoading = false;
BABYLON.SceneLoader.OnPluginActivatedObservable.add((plugin) => {
this._currentPluginName = plugin.name;
if (this._currentPluginName === "gltf") {
const loader = plugin
// loader.transparencyAsCoverage = this.props.globalState.commerceMode;
loader.validate = true;
// loader.onExtensionLoadedObservable.add((extension: import("@babylonjs/loaders/glTF/index").IGLTFLoaderExtension) => {
// this.props.globalState.glTFLoaderExtensions[extension.name] = extension;
// });
loader.onValidatedObservable.add((results) => {
if (results.issues.numErrors > 0) {
// this.props.globalState.showDebugLayer();
}
});
}
});
}
onSceneReady(scene) {
this.scene = scene;
this.scene.onPointerDown = this.onPointerDown;
this.scene.onPointerUp = this.onPointerUp;
this.engine = scene.getEngine();
this.engine.clearInternalTexturesCache();
this.canvas = this.engine.getRenderingCanvas();
if (this.props.noRenderLoop) {
this.engine.setHardwareScalingLevel(100);
} else if (window.innerWidth > 500) {
this.engine.setHardwareScalingLevel(0.7);
} else {
this.engine.setHardwareScalingLevel(1);
}
scene.autoClear = Boolean(this.props.forceAutoClear);
this.prepareCamera()
// this.setupCamera();
// this.setupLights();
this.scene.createDefaultEnvironment({
// createGround: false,
createSkybox: false,
});
// this.scene.clearColor = new Color4(236/255, 240/255, 241/255, 1);
// this.scene.ambientColor = new Color4(236/255, 240/255, 241/255, 1);
this.module.sceneSubject.next(this.scene);
this.module.cameraSubject.next(this.camera);
this.module.engineSubject.next(this.engine);
const filesInput = new BABYLON.FilesInput(
this.engine,
this.scene,
(sceneFile, scene) => {
scene.createDefaultCamera(true);
scene.createDefaultLight();
console.log("Scene loaded")
},
progress => {
console.log("Progress")
console.log(progress)
},
null,
remaining => {
console.log("Texture loaded")
console.log(remaining)
},
files => {
BABYLON.Tools.ClearLogCache();
},
null,
(_, _1, message) => {
console.log("Error")
console.log(message)
});
const canvas = document.getElementById("BaseRenderer");
filesInput.monitorElementForDragNDrop(canvas);
}
prepareCamera() {
// Attach camera to canvas inputs
if (!this.scene.activeCamera) {
this.scene.createDefaultCamera(true);
const camera = this.scene.activeCamera;
if (this._currentPluginName === "gltf") {
// glTF assets use a +Z forward convention while the default camera faces +Z. Rotate the camera to look at the front of the asset.
camera.alpha += Math.PI;
}
// Enable camera's behaviors
camera.useFramingBehavior = true;
const framingBehavior = camera.getBehaviorByName("Framing");
framingBehavior.framingTime = 0;
framingBehavior.elevationReturnTime = -1;
if (this.scene.meshes.length) {
camera.lowerRadiusLimit = null;
const worldExtends = this.scene.getWorldExtends(function (mesh) {
return mesh.isVisible && mesh.isEnabled();
});
framingBehavior.zoomOnBoundingInfo(worldExtends.min, worldExtends.max);
}
if (this.props.autoRotate) {
camera.useAutoRotationBehavior = true;
}
if (this.props.cameraPosition) {
camera.setPosition(this.props.cameraPosition);
}
camera.pinchPrecision = 200 / camera.radius;
camera.upperRadiusLimit = 5 * camera.radius;
camera.wheelDeltaPercentage = 0.01;
camera.pinchDeltaPercentage = 0.01;
}
this.scene.activeCamera.attachControl();
}
setupCamera() {
this.camera = new BABYLON.ArcRotateCamera("Camera", 3 * Math.PI / 2, -Math.PI / 2, 50, Vector3.Zero(), this.scene);
this.camera.useFramingBehavior = true;
// this.camera.position = new Vector3(100, 70, 136);
// this.camera.radius = Math.max(220, 130000 * (1 / window.innerWidth));
// this.camera.lowerRadiusLimit = 130;
// this.camera.upperRadiusLimit = 700;
// this.camera.panningSensibility = 0; // Prevents Right-Click Drag to Translate.
this.camera.attachControl(this.canvas, true);
}
setupLights() {
// this.light = new BABYLON.DirectionalLight('light', new Vector3(0, -1, .6), this.scene);
// this.light.intensity = 1.3;
}
onRender(scene) {
if (!this.camera) {
return;
}
const curZoom = this.camera.inertialRadiusOffset;
if (curZoom !== this.lastZoom) {
if (!this.renderRequestStream.isRendering()) {
this.renderRequestStream.lease(500);
}
this.scenePointerDownSubject.next();
this.lastZoom = curZoom;
}
this.renderSubject.next(scene);
}
render() {
let engineOptions = {};
const style = this.props.style || {width: "100%", height: "100%"}
return (
<BaseRenderer
id="BaseRenderer"
className={"none"}
style={style}
antialias
adaptToDeviceRatio={true}
onSceneReady={this.onSceneReady}
engineOptions={engineOptions}
onRender={this.onRender}
noRenderLoop={this.props.noRenderLoop}
resetSceneRequestSubject={this.resetSceneRequestSubject}
/>
)
}
}
export default withModule(Base3DScene);