Can't get DeviceOrientationControls to work - javascript

I've been trying for over a week now to get the orientation controls of my smartphone to control my three js scene. I had saved an example which was placed under a tutorial, I lost the tutorial but found the example. I looked at how he managed to get the controls working and I can't seem to get the same effect. I hope someone else might spot it...
This is my script.js (I'm loading threejs via cdn in my index.html)
import {sets} from './data/';
import threeOrbitControls from 'three-orbit-controls';
import ColladaLoader from 'three-collada-loader';
import threeStereoEffect from 'three-stereo-effect';
// import FirstPersonControls from 'three-first-person-controls';
const DeviceOrientationControls = require(`./modules/util/DeviceOrientationControls`);
import {BufferLoader} from './modules/sound';
import {SpawnObject} from './modules/render';
const OrbitControls = threeOrbitControls(THREE);
const StereoEffect = threeStereoEffect(THREE);
let scene, camera, renderer, element, container, controls;
let audioCtx, bufferLoader;
const notes = [];
let stereoEffect = null;
const init = () => {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
audioCtx = new AudioContext();
bufferLoader = new BufferLoader(audioCtx);
bufferLoader.load(sets.drums)
.then(data => spawnObject(data));
initEnvironment();
};
const spawnObject = data => {
for (let i = 0;i < 5;i ++) {
const bol = new SpawnObject(`object.dae`, audioCtx, data[0], scene, false);
notes.push(bol);
}
// console.log(notes);
};
const initEnvironment = () => {
//Three.js Scene
scene = new THREE.Scene();
//Create renderer, set size + append to the container
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
element = renderer.domElement;
container = document.querySelector(`main`);
container.appendChild(element);
//Create camera, set position + add to scene
camera = new THREE.PerspectiveCamera(
45, window.innerWidth / window.innerHeight,
1, 10000
);
camera.position.set(0, 0, 2);
camera.lookAt(scene.position);
//Creates stereo effect
stereoEffect = new StereoEffect(renderer);
stereoEffect.setSize(window.innerWidth, window.innerHeight);
//Controls
controls = new OrbitControls(camera);
// controls = new THREE.OrbitControls(camera, element);
// camera.position.x = 100;
// camera.position.y = 1000;
// camera.position.z = 3000;
const setOrientationControls = e => {
if (!e.alpha) {
return;
}
controls = new THREE.DeviceOrientationControls(camera, true);
controls.connect();
controls.update();
element.addEventListener(`click`, fullscreen, false);
window.removeEventListener(`deviceorientation`, setOrientationControls, true);
};
window.addEventListener(`deviceorientation`, setOrientationControls, true);
//LIGHTS
const light = new THREE.PointLight(0xFFFFFF);
light.position.set(0, 0, 9);
light.castShadow = true;
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
light.shadow.camera.near = 10;
light.shadow.camera.far = 100;
scene.add(light);
// const hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6);
// hemiLight.color.setHSL(0.6, 1, 0.6);
// hemiLight.groundColor.setHSL(0.095, 1, 0.75);
// hemiLight.position.set(0, 500, 0);
// scene.add(hemiLight);
//
// const dirLight = new THREE.DirectionalLight(0xffffff, 1);
// dirLight.color.setHSL(0.1, 1, 0.95);
// dirLight.position.set(- 1, 1.75, 1);
// dirLight.position.multiplyScalar(50);
// scene.add(dirLight);
// dirLight.castShadow = true;
//FLOOR
const matFloor = new THREE.MeshPhongMaterial();
const geoFloor = new THREE.BoxGeometry(2000, 1, 2000);
const mshFloor = new THREE.Mesh(geoFloor, matFloor);
matFloor.color.set(0x212E39);
mshFloor.receiveShadow = true;
mshFloor.position.set(0, - 1, 0);
scene.add(mshFloor);
//ENVIRONMENT
const loader = new ColladaLoader();
loader.load(`../assets/environment.dae`, collada => {
collada.scene.traverse(child => {
child.castShadow = true;
child.receiveShadow = true;
});
scene.add(collada.scene);
render();
});
};
controls = THREE.DeviceOrientationControls;
console.log(controls);
function setOrientationControls(e) {
if (!e.alpha) {
return;
}
controls = new THREE.DeviceOrientationControls(camera, true);
controls.connect();
controls.update();
element.addEventListener(`click`, fullscreen, false);
window.removeEventListener(`deviceorientation`, setOrientationControls, true);
}
window.addEventListener(`deviceorientation`, setOrientationControls, true);
const render = () => {
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.setClearColor(0xdddddd, 1);
stereoEffect.render(scene, camera);
requestAnimationFrame(render);
};
function fullscreen() {
if (container.requestFullscreen) {
container.requestFullscreen();
} else if (container.msRequestFullscreen) {
container.msRequestFullscreen();
} else if (container.mozRequestFullScreen) {
container.mozRequestFullScreen();
} else if (container.webkitRequestFullscreen) {
container.webkitRequestFullscreen();
}
}
init();

I'm not sure how I fixed it, but I didn't use the function around the defining of the DeviceOrientationControls, instead I used a regex to check whether I'm on the browser or on a mobile device.
That seems to work.

Related

animate a .fbx in three.js

I want to animate this cow with the file sleep.fbx but the cow is rendering but not animating and i don't found the error.render cow sleep, however i couldn't find the error in the code:
//Variables for setup
import * as THREE from 'three';
import {FBXLoader} from 'three/addons/loaders/FBXLoader.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
let container;
let camara;
let renderer;
let scene;
function init(){
container= document.querySelector('.scene');
console.log(GLTFLoader);
//Create scene
scene = new THREE.Scene();
const fov=35;
const aspect= container.clientWidth/container.clientHeight;
const near= 0.1;
const far = 1000;
//camara setup
camara = new THREE.PerspectiveCamera(fov,aspect,near, far);
camara.position.set(0,2,10);
const ambient = new THREE.AmbientLight(0x404040, 2);
scene.add(ambient);
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(10, 25, 20);
scene.add(light);
//renderer setup
renderer = new THREE.WebGLRenderer({antialias:true, alpha:true});
renderer.setSize(container.clientWidth,container.clientHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.outputEncoding = THREE.sRGBEncoding;
container.appendChild(renderer.domElement);
const controls = new OrbitControls(camara, renderer.domElement)
controls.enableDamping = true
controls.target.set(0, 1, 0)
// Setup Textures and the FBX Files URLs
let Cow = "static/lib/admin-3.2.0/3d_1/FBX/source/Cow.FBX";
let modelUrl2 = "static/lib/admin-3.2.0/3d_1/textures/Cow.tga.png";
let modelUrl3 = "static/lib/admin-3.2.0/3d_1/textures/Eye_Brown.tga.png";
let modelUrl4 = "static/lib/admin-3.2.0/3d_1/textures/Cow_Normals.tga.png";
let modelUrl5 = "static/lib/admin-3.2.0/3d_1/textures/Eye_Shine.tga.png";
// Setup Animations and the FBX Files URLs
let Animate_Sleep = "static/lib/admin-3.2.0/3d_1/FBX/source/animations/Sleep.FBX";
const fbxLoader = new FBXLoader()
fbxLoader.load(Cow, function(fbx) {
//Initialize each png Textures
let textureLoader = new THREE.TextureLoader();
const texture1 = textureLoader.load( modelUrl2 );
texture1.flipY = true;
const texture2 = textureLoader.load( modelUrl3 );
texture2.flipY = true;
const normalTexture = textureLoader.load( modelUrl4 );
normalTexture.flipY = true;
const Eye_Shine = textureLoader.load( modelUrl5 );
normalTexture.flipY = false;
fbx.traverse((child) => {
if ( child.isMesh && child.geometry ) {
// note: for a multi-material mesh, `o.material` may be an array,
// in which case you'd need to set `.map` on each value.s
if (child.name == "Cow_Mesh") {
child.material = new THREE.MeshPhongMaterial({
map:texture1,
normalMap: normalTexture
})}
else if (child.name == "Eye_Left") {
child.material = new THREE.MeshPhongMaterial({
map:texture2,
normalMap: Eye_Shine})
};
if (child.name == "Eye_Right") {
child.material = new THREE.MeshPhongMaterial({
map:texture2,
normalMap: Eye_Shine})
};
child.receiveShadow = true;
child.castShadow = true;
}
});
fbx.scale.setScalar(0.02);
fbx.rotation.x = -1.5;
scene.add(fbx);
const mixer = new THREE.AnimationMixer(fbx);
// Carga las animaciones
const loaderAnimations = new FBXLoader();
loaderAnimations.load(Animate_Sleep, function (anim) {
// Crea un AnimationMixer
let action = mixer.clipAction(anim.animations[0]);
console.log(action);
action.play();
});
animate();
const clock = new THREE.Clock()
function animate() {
requestAnimationFrame(animate);
controls.update(scene);
/* mixer.update(clock.getDelta()) ; */
renderer.render(scene,camara);}
});
}
init()
function onWindowResize() {
camara.aspect = container.clientWidth/container.clientHeight;
camara.updateProjectionMatrix();
renderer.setSize(container.clientWidth, container.clientHeight);
}
window.addEventListener('resize', onWindowResize);
I am trying to animate the cow with the function THREE.AnimationMixer(fbx); but is not animating and i am getting a empty canvas when i am trying to animate the cow, i want to animate and renderize the sleep.FBX in the webpage.

ThreeJS is not casting shadows

I am building a basic Three JS application. Basically, I am learning Three JS and so that I am experimenting with it. Now, I am building a scene where there is a floor, an object and a light. I want to see the shadow of the object on the floor due to light. This is my code.
import * as THREE from 'three';
const scene = new THREE.Scene();
const aspect_ratio = window.innerWidth / window.innerHeight;
const camera = new THREE.PerspectiveCamera(75, aspect_ratio, 1, 10000);
camera.position.z = 500;
scene.add(camera);
const renderer = new THREE.WebGLRenderer();
renderer.shadowMapEnabled = true;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.append(renderer.domElement);
var shape = new THREE.TorusGeometry(100, 50, 8, 20);
var cover = new THREE.MeshPhongMaterial();
cover.emissive.setRGB(0.8, 0.1, 0.1);
cover.specular.setRGB(0.9, 0.9, 0.9);
var donut = new THREE.Mesh(shape, cover); scene.add(donut);
donut.castShadow = true;
var sunlight = new THREE.DirectionalLight();
sunlight.intensity = 0.5;
sunlight.position.set(100, 100, 100);
scene.add(sunlight);
sunlight.castShadow = true;
var shape = new THREE.PlaneGeometry(1500, 1500);
var cover = new THREE.MeshBasicMaterial();
var ground = new THREE.Mesh(shape, cover);
scene.add(ground);
ground.position.set(0, -180, 0);
ground.rotation.set(-Math.PI/2, 0, 0);
ground.receiveShadow = true;
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
I am supposed to see the shadow of the donut on the floor. But this is what I see instead without shadow.
What is wrong with my code and how can I fix it?
You have to make the ground to receive shadow
to do this:
ground.receiveShadow = true;
There are multiple issues in your code. The most important problem is that you do not configure your shadow frustum correctly. Besides, MeshBasicMaterial is not affected by light and thus can't receive shadows. Try it like so:
const scene = new THREE.Scene();
const aspect_ratio = window.innerWidth / window.innerHeight;
const camera = new THREE.PerspectiveCamera(75, aspect_ratio, 1, 10000);
camera.position.z = 500;
scene.add(camera);
const renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.append(renderer.domElement);
const donutGeometry = new THREE.TorusGeometry(100, 50, 8, 20);
const donutMaterial = new THREE.MeshPhongMaterial();
donutMaterial.emissive.setRGB(0.8, 0.1, 0.1);
donutMaterial.specular.setRGB(0.9, 0.9, 0.9);
const donut = new THREE.Mesh(donutGeometry, donutMaterial);
scene.add(donut);
donut.castShadow = true;
var sunlight = new THREE.DirectionalLight();
sunlight.intensity = 0.5;
sunlight.position.set(100, 100, 100);
scene.add(sunlight);
sunlight.castShadow = true;
sunlight.shadow.camera.top = 200;
sunlight.shadow.camera.bottom = - 200;
sunlight.shadow.camera.left = - 200;
sunlight.shadow.camera.right = 200;
sunlight.shadow.camera.near = 1;
sunlight.shadow.camera.far = 1000;
//scene.add( new THREE.CameraHelper( sunlight.shadow.camera ) );
const groundGeometry = new THREE.PlaneGeometry(1500, 1500);
const groundMaterial = new THREE.MeshPhongMaterial();
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
scene.add(ground);
ground.position.set(0, -180, 0);
ground.rotation.set(-Math.PI/2, 0, 0);
ground.receiveShadow = true;
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.144/build/three.min.js"></script>

Sprite use png map . But it doesn't display properly when scene contains Bloom. What shound i do?

I loaded a Sprite in a scene with Bloom, the trouble is that my Sprite map is using an externally loaded Png texture. Not the usual solid color material. I know it's possible to make all the textures black first and then back to the original color. But if my material is using the png Map.what should I do? Let the Sprite display normally and not have Bloom .
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from '../jsm/controls/OrbitControls.js';
import Stats from '../jsm/libs/stats.module.js';
import { GUI } from '../jsm/libs/lil-gui.module.min.js';
import { EffectComposer } from '../jsm/postprocessing/EffectComposer.js';
import { RenderPass } from '../jsm/postprocessing/RenderPass.js';
import { UnrealBloomPass } from '../jsm/postprocessing/UnrealBloomPass.js';
import { FBXLoader } from '../Loader/FBXLoader/FBXLoader.js';
import { OBJLoader } from '../Loader/OBJLoader.js';
import { MTLLoader } from '../Loader/MTLLoader.js'
import { GLTFLoader } from "../Loader/GLTFLoader.js";
import { ShaderPass } from '../jsm/postprocessing/ShaderPass.js';
const ENTIRE_SCENE = 0, BLOOM_SCENE = 1;
const bloomLayer = new THREE.Layers();
bloomLayer.set(BLOOM_SCENE);
let params = {
exposure: 1,
bloomThreshold: 0.41,
bloomStrength: 0.66,
bloomRadius: 0.05,
scene: 'Scene with Glow'
};
//set MeshBasicMaterial
const darkMaterial = new THREE.MeshBasicMaterial({ color: 'black' });
const materials = {};
/*--------renderer--------*/
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
//add scene
const scene = new THREE.Scene();
/*--------camera--------*/
const camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 0.1, 100000000);
camera.position.set(0, 10, 10);
camera.lookAt(0, 0, 0);
//makeLabelCanvas
function makeLabelCanvas(size, name) {
const borderSize = 0;
const ctx = document.createElement('canvas').getContext('2d');
const font = `${size}px bold sans-serif`;
ctx.font = font;
// measure how long the name will be
const doubleBorderSize = borderSize * 2;
const width = ctx.measureText(name).width + doubleBorderSize;
const height = 70 + doubleBorderSize;
ctx.canvas.width = width;
ctx.canvas.height = height;
console.log(ctx);
ctx.font = font;
ctx.textBaseline = 'top';
return ctx.canvas;
}
/*--------OrbitControls--------*/
let controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0);
controls.enablePan = false;
controls.maxPolarAngle = Math.PI / 2;
controls.enableDamping = true;
//Render
const renderScene = new RenderPass(scene, camera);
const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85);
bloomPass.threshold = params.bloomThreshold;
bloomPass.strength = params.bloomStrength;
bloomPass.radius = params.bloomRadius;
const bloomComposer = new EffectComposer(renderer);
bloomComposer.renderToScreen = false;
bloomComposer.addPass(renderScene);
bloomComposer.addPass(bloomPass);
const finalPass = new ShaderPass(
new THREE.ShaderMaterial({
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: bloomComposer.renderTarget2.texture }
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
defines: {}
}), 'baseTexture'
);
finalPass.needsSwap = true;
const finalComposer = new EffectComposer(renderer);
finalComposer.addPass(renderScene);
finalComposer.addPass(finalPass);
/*--------Stats--------*/
const stats = Stats();
stats.showPanel(0);
/*--------AmbientLight-1--------*/
scene.add(new THREE.AmbientLight(0xffffff, 1));
//light1
const light1 = new THREE.PointLight(0xddffdd, 1);
light1.position.z = 0;
light1.position.y = 300;
light1.position.x = 200;
scene.add(light1);
/*--------cube--------*/
const geometry = new THREE.BoxGeometry(4, 4, 4);
const material = new THREE.MeshBasicMaterial({ color: 0x000050 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
/*--------label--------*/
const canvas = makeLabelCanvas(100, 'name');
const texture = new THREE.CanvasTexture(canvas);
texture.wrapS = THREE.ClampToEdgeWrapping;
texture.wrapT = THREE.ClampToEdgeWrapping;
//Material
const loader = new THREE.TextureLoader();
const labelMaterial = new THREE.SpriteMaterial({
map: loader.load('../img/moudle-lable/Wood-storage-tank/stokehold.png'),
side: THREE.DoubleSide,
transparent: true,
});
const label = new THREE.Sprite(labelMaterial);
cube.add(label);
label.position.x = -5;
label.position.y = 3;
label.position.z = 0;
const label_BaseScale_X = 0.05;
const label_BaseScale_Y = 0.05;
label.scale.x = canvas.width * label_BaseScale_X;
label.scale.y = canvas.height * label_BaseScale_Y;
//window.onresize
window.onresize = function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
};
function disposeMaterial(obj) {
if (obj.material) {
obj.material.dispose();
}
}
//render
function render() {
switch (params.scene) {
case 'Scene only':
renderer.render(scene, camera);
break;
case 'Scene with Glow':
default:
// render scene with bloom
renderBloom(true);
// render the entire scene, then render bloom scene on top
finalComposer.render();
break;
}
}
function renderBloom(mask) {
if (mask === true) {
renderer.setClearColor(0x000000); // all must be black, including background
scene.traverse(darkenNonBloomed);
bloomComposer.render();
renderer.setClearColor(0xffffff); // set the color you want
scene.traverse(restoreMaterial);
} else {
camera.layers.set(BLOOM_SCENE);
bloomComposer.render();
camera.layers.set(ENTIRE_SCENE);
}
}
function darkenNonBloomed(obj) {
if (obj.isMesh && bloomLayer.test(obj.layers) === false) {
materials[obj.uuid] = obj.material;
obj.material = darkMaterial;
}
}
function restoreMaterial(obj) {
if (materials[obj.uuid]) {
obj.material = materials[obj.uuid];
delete materials[obj.uuid];
}
}
function animate() {
render();
requestAnimationFrame(animate);
};
animate();
var axes = new THREE.AxisHelper(20);
scene.add(axes);
</script>
this is my png
And this is use PlaneBufferGeometry do .
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from '../jsm/controls/OrbitControls.js';
import Stats from '../jsm/libs/stats.module.js';
import { GUI } from '../jsm/libs/lil-gui.module.min.js';
import { EffectComposer } from '../jsm/postprocessing/EffectComposer.js';
import { RenderPass } from '../jsm/postprocessing/RenderPass.js';
import { UnrealBloomPass } from '../jsm/postprocessing/UnrealBloomPass.js';
import { FBXLoader } from '../Loader/FBXLoader/FBXLoader.js';
import { OBJLoader } from '../Loader/OBJLoader.js';
import { MTLLoader } from '../Loader/MTLLoader.js'
import { GLTFLoader } from "../Loader/GLTFLoader.js";
import { ShaderPass } from '../jsm/postprocessing/ShaderPass.js';
const ENTIRE_SCENE = 0, BLOOM_SCENE = 1;
const bloomLayer = new THREE.Layers();
bloomLayer.set(BLOOM_SCENE);
let params = {
exposure: 1,
bloomThreshold: 0.41,
bloomStrength: 0.66,
bloomRadius: 0.05,
scene: 'Scene with Glow'
};
//set MeshBasicMaterial
const darkMaterial = new THREE.MeshBasicMaterial({ color: 'black' });
const materials = {};
/*--------renderer--------*/
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
//add scene
const scene = new THREE.Scene();
/*--------camera--------*/
const camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 0.1, 100000000);
camera.position.set(0, 10, 10);
camera.lookAt(0, 0, 0);
//makeLabelCanvas
function makeLabelCanvas(size, name) {
const borderSize = 0;
const ctx = document.createElement('canvas').getContext('2d');
const font = `${size}px bold sans-serif`;
ctx.font = font;
// measure how long the name will be
const doubleBorderSize = borderSize * 2;
const width = ctx.measureText(name).width + doubleBorderSize;
const height = 70 + doubleBorderSize;
ctx.canvas.width = width;
ctx.canvas.height = height;
console.log(ctx);
ctx.font = font;
ctx.textBaseline = 'top';
return ctx.canvas;
}
/*--------OrbitControls--------*/
let controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0);
controls.enablePan = false;
controls.maxPolarAngle = Math.PI / 2;
controls.enableDamping = true;
//Render
const renderScene = new RenderPass(scene, camera);
const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85);
bloomPass.threshold = params.bloomThreshold;
bloomPass.strength = params.bloomStrength;
bloomPass.radius = params.bloomRadius;
const bloomComposer = new EffectComposer(renderer);
bloomComposer.renderToScreen = false;
bloomComposer.addPass(renderScene);
bloomComposer.addPass(bloomPass);
const finalPass = new ShaderPass(
new THREE.ShaderMaterial({
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: bloomComposer.renderTarget2.texture }
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
defines: {}
}), 'baseTexture'
);
finalPass.needsSwap = true;
const finalComposer = new EffectComposer(renderer);
finalComposer.addPass(renderScene);
finalComposer.addPass(finalPass);
/*--------Stats--------*/
const stats = Stats();
stats.showPanel(0);
/*--------AmbientLight-1--------*/
scene.add(new THREE.AmbientLight(0xffffff, 1));
//light1
const light1 = new THREE.PointLight(0xddffdd, 1);
light1.position.z = 0;
light1.position.y = 300;
light1.position.x = 200;
scene.add(light1);
/*--------cube--------*/
const geometry = new THREE.BoxGeometry(4, 4, 4);
const material = new THREE.MeshBasicMaterial({ color: 0x000050 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
/*--------label--------*/
const labelGeometry = new THREE.PlaneBufferGeometry(1, 1);
const canvas = makeLabelCanvas(100, 'name');
const texture = new THREE.CanvasTexture(canvas);
texture.wrapS = THREE.ClampToEdgeWrapping;
texture.wrapT = THREE.ClampToEdgeWrapping;
//Material
const loader = new THREE.TextureLoader();
const labelMaterial = new THREE.MeshBasicMaterial({
map: loader.load('../img/moudle-lable/Wood-storage-tank/stokehold.png'),
side: THREE.DoubleSide,
transparent: true,
});
const label = new THREE.Mesh(labelGeometry, labelMaterial);
cube.add(label);
label.position.x = -5;
label.position.y = 3;
label.position.z = 0;
const label_BaseScale_X = 0.05;
const label_BaseScale_Y = 0.05;
label.scale.x = canvas.width * label_BaseScale_X;
label.scale.y = canvas.height * label_BaseScale_Y;
//window.onresize
window.onresize = function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
};
function disposeMaterial(obj) {
if (obj.material) {
obj.material.dispose();
}
}
//render
function render() {
switch (params.scene) {
case 'Scene only':
renderer.render(scene, camera);
break;
case 'Scene with Glow':
default:
// render scene with bloom
renderBloom(true);
// render the entire scene, then render bloom scene on top
finalComposer.render();
break;
}
}
function renderBloom(mask) {
if (mask === true) {
renderer.setClearColor(0x000000); // all must be black, including background
scene.traverse(darkenNonBloomed);
bloomComposer.render();
renderer.setClearColor(0xffffff); // set the color you want
scene.traverse(restoreMaterial);
} else {
camera.layers.set(BLOOM_SCENE);
bloomComposer.render();
camera.layers.set(ENTIRE_SCENE);
}
}
function darkenNonBloomed(obj) {
if (obj.isMesh && bloomLayer.test(obj.layers) === false) {
materials[obj.uuid] = obj.material;
obj.material = darkMaterial;
}
}
function restoreMaterial(obj) {
if (materials[obj.uuid]) {
obj.material = materials[obj.uuid];
delete materials[obj.uuid];
}
}
function animate() {
controls.update();
render();
requestAnimationFrame(animate);
};
animate();
var axes = new THREE.AxisHelper(20);
scene.add(axes);
</script>
It displays normally, but the PlaneBufferGeometry doesn't always face the camera.
Here are examples if needed https://smile881225.github.io/AskQuestions/backup/標籤發光問題.html

Using a GLTF model as the Scene in Three.js

I am new to Three.js. I am having issues using a gltf model as the actual scene and not part of the scene in three.js. The gltf model is an apartment. I want the scene to load from inside the apartment and not outside the apartment. the controls should work within the apartment too. So far, I have loaded the model on the scene but I can't get the scene to render from inside the model.
Here is my code in Typescript and also JavaScript been at it for weeks now. Any help will be much appreciated. Thank you so much.
Typescript code
import * as THREE from '/build/three.module.js'
import { OrbitControls } from '/jsm/controls/OrbitControls'
import { GLTFLoader } from '/jsm/loaders/GLTFLoader'
import Stats from '/jsm/libs/stats.module'
const scene: THREE.Scene = new THREE.Scene()
const axesHelper = new THREE.AxesHelper(5)
//scene.add(axesHelper)
var light = new THREE.SpotLight();
light.position.set(5, 5, 5)
scene.add(light);
const camera: THREE.PerspectiveCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 2
const renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer()
//renderer.physicallyCorrectLights = true
//renderer.shadowMap.enabled = true
renderer.outputEncoding = THREE.sRGBEncoding
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
const controls = new OrbitControls(camera, renderer.domElement)
const loader = new GLTFLoader()
loader.load(
'apartment.glb',
function (gltf) {
// gltf.scene.traverse(function (child) {
// if ((<THREE.Mesh>child).isMesh) {
// let m = <THREE.Mesh>child
// m.receiveShadow = true
// m.castShadow = true
// }
// if ((<THREE.Light>child).isLight) {
// let l = <THREE.Light>child
// l.castShadow = true
// //l.shadow.bias = -.003
// l.shadow.mapSize.width = 2048
// l.shadow.mapSize.height = 2048
// }
// })
scene.add(gltf.scene);
},
(xhr) => {
console.log((xhr.loaded / xhr.total * 100) + '% loaded')
},
(error) => {
console.log(error);
}
);
window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
render()
}
const stats = Stats()
document.body.appendChild(stats.dom)
var animate = function () {
requestAnimationFrame(animate)
controls.update()
render()
stats.update()
};
function render() {
renderer.render(scene, camera)
}
animate();
JavaScript code
import * as THREE from '/build/three.module.js';
import { OrbitControls } from '/jsm/controls/OrbitControls';
import { GLTFLoader } from '/jsm/loaders/GLTFLoader';
import Stats from '/jsm/libs/stats.module';
const scene = new THREE.Scene();
const axesHelper = new THREE.AxesHelper(5);
//scene.add(axesHelper)
var light = new THREE.SpotLight();
light.position.set(5, 5, 5);
scene.add(light);
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 2;
const renderer = new THREE.WebGLRenderer();
//renderer.physicallyCorrectLights = true
//renderer.shadowMap.enabled = true
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
const loader = new GLTFLoader();
loader.load('apartment.glb', function (gltf) {
// gltf.scene.traverse(function (child) {
// if ((<THREE.Mesh>child).isMesh) {
// let m = <THREE.Mesh>child
// m.receiveShadow = true
// m.castShadow = true
// }
// if ((<THREE.Light>child).isLight) {
// let l = <THREE.Light>child
// l.castShadow = true
// //l.shadow.bias = -.003
// l.shadow.mapSize.width = 2048
// l.shadow.mapSize.height = 2048
// }
// })
scene.add(gltf.scene);
}, (xhr) => {
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
}, (error) => {
console.log(error);
});
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
render();
}
const stats = Stats();
document.body.appendChild(stats.dom);
var animate = function () {
requestAnimationFrame(animate);
controls.update();
render();
stats.update();
};
function render() {
renderer.render(scene, camera);
}
animate();
Finally was able to solve my issue.
firstly I had to use a plane model that is with no roof
secondly the pivot point was properly at the center and the model was on the plane grid, unlike the first model I was working with.
with the model opened the room was what was rendered in the scene and not the entire model itself and because the pivot point was in the middle and the model on the plane, not below or above it, I did not have to look for it in the scene when it rendered. Thank you for reading and trying to help.
because I had solved this problem I was able to load multiple glb models and place them where I wanted in the scene without hassle.
my advice if you want to use a model as your scene make sure the pivot point is at the center and the model is on the grid, not over or below it. also make sure its an open model so your light and camera can see inside.
here was my final code.
import * as THREE from '/build/three.module.js'
import { OrbitControls } from '/jsm/controls/OrbitControls'
import { GLTFLoader } from '/jsm/loaders/GLTFLoader'
// import Stats from '/jsm/libs/stats.module'
// import { GUI } from '/jsm/libs/dat.gui.module'
const scene: THREE.Scene = new THREE.Scene()
const axesHelper = new THREE.AxesHelper(5)
//scene.add(axesHelper)
const light = new THREE.SpotLight(0xffa95c,4);
light.position.set(-50,50,50);
light.castShadow = true;
scene.add( light );
var hemiLight = new THREE.HemisphereLight(0xffeeb1, 0x080820, 4);
scene.add(hemiLight);
var light3 = new THREE.DirectionalLight( 0xffffff );
light3.position.set( 0, 200, 100 );
light3.castShadow = true;
light3.shadow.mapSize.width = 2048;
light3.shadow.mapSize.height = 2048;
light3.shadow.camera.top = 3000;
light3.shadow.camera.bottom = -3000;
light3.shadow.camera.left = -3000;
light3.shadow.camera.right = 3000;
light3.shadow.camera.far = 3000;
scene.add( light );
const camera: THREE.PerspectiveCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 2
camera.position.y = 2
camera.position.x = 2
const renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer()
//renderer.physicallyCorrectLights = true
//renderer.shadowMap.enabled = true
renderer.outputEncoding = THREE.sRGBEncoding
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
// var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
// mesh.rotation.x = - Math.PI / 2;
// //mesh.position.y = -100;
// mesh.receiveShadow = true;
// //this.scene.add( mesh );
// var grid = new THREE.GridHelper( 2000, 40, 0x000000, 0x000000 );
// //grid.position.y = -100;
// // grid.material.opacity = 0.2;
// // grid.material.transparent = true;
const raycaster = new THREE.Raycaster();
const controls = new OrbitControls(camera, renderer.domElement)
controls.screenSpacePanning = true
controls.target.set(0, 1, 0)
controls.minDistance = 5;
controls.maxDistance = 10;
// const backGroundTexture = new THREE.CubeTextureLoader().load(["img/py_eso0932a.jpg", "img/ny_eso0932a.jpg", "img/py_eso0932a.jpg", "img/ny_eso0932a.jpg", "img/pz_eso0932a.jpg", "img/nz_eso0932a.jpg"]);
// scene.background = backGroundTexture;
const loader = new GLTFLoader()
loader.load(
'models3/untitled.glb',
function (gltf) {
scene.add(gltf.scene);
gltf.scene.position.set(0,-2,3)
},
(xhr) => {
console.log((xhr.loaded / xhr.total * 100) + '% loaded')
},
(error) => {
console.log(error);
}
);
loader.load(
'models3/man.glb',
function (gltf1) {
scene.add(gltf1.scene);
gltf1.scene.position.set(1,-1.3,0)
gltf1.scene.scale.set(2,2,2)
},
(xhr) => {
console.log((xhr.loaded / xhr.total * 100) + '% loaded')
},
(error) => {
console.log(error);
}
);
loader.load(
'models3/jack_daniels.glb',
function (gltf2) {
gltf2.scene.traverse(function (child) {
if ((<THREE.Mesh>child).isMesh) {
let m = <THREE.Mesh>child
m.receiveShadow = true
m.castShadow = true;
//(<THREE.MeshStandardMaterial>m.material).flatShading = true
//sceneMeshes.push(m)
}
if ((<THREE.Light>child).isLight) {
let l = <THREE.Light>child
l.castShadow = true
l.shadow.bias = -.003
l.shadow.mapSize.width = 2048
l.shadow.mapSize.height = 2048
}
scene.add(gltf2.scene);
gltf2.scene.position.set(-1,0.55,-1)
gltf2.scene.scale.set(0.15,0.15,0.15)})
},
(xhr) => {
console.log((xhr.loaded / xhr.total * 100) + '% loaded')
},
(error) => {
console.log(error);
}
);
// renderer.domElement.addEventListener('dblclick', onDoubleClick, false);
// renderer.domElement.addEventListener('mousemove', onMouseMove, false);
// function onMouseMove(event: MouseEvent) {
// const mouse = {
// x: (event.clientX / renderer.domElement.clientWidth) * 2 - 1,
// y: -(event.clientY / renderer.domElement.clientHeight) * 2 + 1
// }
// //console.log(mouse)
// raycaster.setFromCamera(mouse, camera);
window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
render()
}
// const stats = Stats()
// document.body.appendChild(stats.dom)
var animate = function () {
requestAnimationFrame(animate)
// light.position.set(
// camera.position.x + 10,
// camera.position.y + 10,
// camera.position.z + 10,
// );
controls.update()
render()
// stats.update()
};
function render() {
renderer.render(scene, camera)
}
animate();
function onDoubleClick(arg0: string, onDoubleClick: any, arg2: boolean) {
throw new Error('Function not implemented.')
}
PLEASE FEEL FREE TO COMMENT IF THERE IS SOMETHING I NEED TO KNOW. I WILL HUMBLY TAKE CORRECTIONS. THANK YOU

ThreeJS: How to replace a cube mesh with a car mesh?

I developed a 3D cube that moves on one axis simulating the accelerometer sensor.
Currently, I have the .obj and .mtl of a toycar which I aim to add to the scene(), but when I remove the
BoxGeometry 3D cube and replace it with the car mesh I got these errors all the time:
I also get this error saying that obj is not defined, even if I defined it globally I still have the same issue:
I checked libraries that exist locally and other function but I can't see where is the problem.
Below is how I load the car model:
const scene = new THREE.Scene();
var loader = new THREE.OBJMTLLoader();
loader.load('https://jyunming-chen.github.io/tutsplus/models/toycar.obj', 'https://jyunming-chen.github.io/tutsplus/models/toycar.mtl',
function (vehicle) {
toycar = vehicle;
toycar.rotateY(-10.99);
scene.add(toycar);
});
and this is my full .HTML code with js implementation:
This is hoq looks like now:
and this is what I am aiming to achieve:
That's my current code:
<html>
<head>
<meta charset="UTF-8">
<script src="./three.min.js"></script>
<script src="./require.js" type="text/javascript"></script>
<script src="./OrbitControls.js"></script>
<script src="./KeyboardState.js"></script>
<script src="./MTLLoader.js"></script>
<script src="./OBJMTLLoader.js"></script>
<script type="module"> import * as THREE from "./three.module.js"</script>
</head>
<body>
<canvas id="canvas" width="1000" height="600" style="border:1px solid #000000;"></canvas>
</body>
<script>
let sensorValue = 0;
let sensorAddr = 0;
var toycar;
StartRetrieveLiveData();
function main() {
const canvas = document.querySelector('#canvas');
const accelPanel = document.querySelector('#accelPanel');
const renderer = new THREE.WebGLRenderer({ alpha: true, canvas });
renderer.setClearColor( 0x626d73, 1 );
var context = canvas.getContext("2d");
var width = window.innerWidth;
var height = window.innerHeight;
const fov = 70;
const aspect = 2;
const near = 20;
const far = 500;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 50, 1.5);
camera.up.set(0, 0, 1);
camera.lookAt(0, 0, 0);
const scene = new THREE.Scene();
// var loader = new THREE.OBJMTLLoader();
// loader.load('https://jyunming-chen.github.io/tutsplus/models/toycar.obj', 'https://jyunming-chen.github.io/tutsplus/models/toycar.mtl',
// function (vehicle) {
// toycar = vehicle;
// toycar.rotateY(-10.99);
// scene.add(toycar);
// });
// An array of objects who's rotation to update
const objects = [];
const radius = 3;
const widthSegments = 3;
const heightSegments = 3;
const sphereGeometry = new THREE.BoxGeometry(radius, widthSegments, heightSegments);
const sunMaterial = new THREE.MeshBasicMaterial({ color: "green", wireframe: false });
const object = new THREE.Mesh(sphereGeometry, sunMaterial);
var cubeAxis = new THREE.AxesHelper(10);
object.add(cubeAxis);
object.scale.set(2, 2, 2);
scene.add(object);
objects.push(object);
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
objects.forEach((obj) => {
sensorValueIndex = ((sensorValue / 16384) * 10);
obj.position.z = ((sensorValue / 16384) * 20);
console.log("AccX: ",sensorValueIndex);
// // Here I take accelerometerX and pass them to the 3D model
// if (sensorAddr === 1) {
// }
});
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
function onMsg(event) {
// console.log(`[message] Data received from server: ${event.data}`);
// console.log("event.data = " + JSON.parse(event.data));
var received_msg = event.data;
var obj = JSON.parse(JSON.parse(received_msg));
if (obj !== null) {
if (
obj.hasOwnProperty("DataMapChangedObjectsAddressValue") &&
obj["DataMapChangedObjectsAddressValue"][0]["DataMapAddress"] !==
undefined
) {
sensorAddr =
obj["DataMapChangedObjectsAddressValue"][0]["DataMapAddress"];
sensorValue =
obj["DataMapChangedObjectsAddressValue"][0]["Value"];
// if (sensorAddr === 1) {
// sensorValueIndex = (sensorValue / 16384) * 500;
// }
}
}
}
function onOpen(e) {
console.log("SSE connected");
}
function onError(e) {
// console.log(`[error] ${error.message}`);
if (e.eventPhase == EventSource.CLOSED) this.source.close();
if (e.target.readyState == EventSource.CLOSED) {
console.log("SSE Disconnected");
} else if (e.target.readyState == EventSource.CONNECTING) {
console.log("SSE Connecting ...");
}
}
function StartRetrieveLiveData() {
if (!!window.EventSource) {
this.source = new EventSource("/sse");
} else {
console.log("Your browser doesn't support SSE");
}
this.source.addEventListener("message", e => this.onMsg(e));
this.source.addEventListener("open", e => this.onOpen(e), false);
this.source.addEventListener("error", e => this.onError(e), false);
// Add here (only mozilla)
main();
// Add here
}
</script>
</html>
Note that when I used a public server the whole thing works just fine, but I used the remote server (the actual server) I get these error and the whole thing doesn't work as expected.
Would appreciate a solution for this.
I solved the problem so I am going to answer this.
Firstly, the document.querySelector('#canvas') should be removed to avoid creating two canvas, because I am calling the libraries in the . This was a silly mistake but I found it finally.
Secondly, the camera position was off and it wasn't really pointing at the car so nothing was shown on the screen. I tweaked the camera.position on the X, Y and Z axis to get it right.
There were bunches of other silly mistakes I found while carefully debugging the code, I am not an expert in the language yet so these mistakes serve as a learning experience for me.
The final working code is below:
let sensorValue = 0;
var toycar;
StartRetrieveLiveData();
var scene, renderer, camera;
var controls, keyboard = new KeyboardState();
var toycar;
function init() {
var width = window.innerWidth;
var height = window.innerHeight;
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setClearColor(0x626d73, 1);
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(10, width / height, 1, 10000);
camera.position.y = -150;
camera.lookAt(new THREE.Vector3(0, 0, 0));
var loader = new THREE.OBJMTLLoader();
loader.load('./toycar.obj', './toycar.mtl',
function (object) {
toycar = object;
toycar.rotateZ(10.99); //toycar.rotateZ(-10.99);
scene.add(toycar);
});
var gridXZ = new THREE.GridHelper(350000, 10000);
gridXZ.setColors(new THREE.Color(0xff0000), new THREE.Color(0xffffff));
scene.add(gridXZ);
var pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(350, 20, 5);
scene.add(pointLight);
var ambientLight = new THREE.AmbientLight(0x111111);
scene.add(ambientLight);
}
function animate() {
var angle = 0;
var speed = 0;
var pos = new THREE.Vector3(0, 0, 0);
var clock = new THREE.Clock();
var dt = clock.getDelta();
var dir = new THREE.Vector3(1, 0, 0);
dir.multiplyScalar(dt * speed);
dir.applyAxisAngle(new THREE.Vector3(0, 0, 0), 10);
pos.add(dir);
if (toycar != undefined) {
sensorValueIndex = ((sensorValue / 16384) * 50);
toycar.scale.set(0.1, 0.1, 0.1);
toycar.position.x = sensorValueIndex;
toycar.position.y = 0;
toycar.position.z = 0;
toycar.rotation.x = (angle + Math.PI);
}
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
function onMsg(event) {
var received_msg = event.data;
var obj = JSON.parse(JSON.parse(received_msg));
if (obj !== null) {
if (
obj.hasOwnProperty("DataMapChangedObjectsAddressValue") &&
obj["DataMapChangedObjectsAddressValue"][0]["DataMapAddress"] !==
undefined
) {
let sensorAddr =
obj["DataMapChangedObjectsAddressValue"][0]["DataMapAddress"];
sensorValue =
obj["DataMapChangedObjectsAddressValue"][0]["Value"];
if (sensorAddr === 1) {
sensorValueIndex = (sensorValue / 16384) * 10;
console.log(sensorValueIndex);
}
}
}
}

Categories