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);
}
}
}
}
Related
js for making a scene with water. I followed the official examples to create the scene, but after loading an external GLTF model I noticed that the reflection does not work well.
In the first frame everything is ok, but as soon as I move the camera all goes wrong.
I think that it's due to my own code for camera motion, but I can't understand why.
Here's the code:
let div = document.body.children[0];
let rect = div.getBoundingClientRect();
// create scene
let scene = new THREE.Scene();
// load boat model
{
let loader = new THREE.GLTFLoader();
// load a glTF resource
loader.load(
// resource URL
"https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Duck/glTF/Duck.gltf",
// called when the resource is loaded
function (gltf) {
let duck = gltf.scene.children[0];
scene.add(duck);
},
// called while loading is progressing
function (xhr) {
console.log(xhr, (xhr.loaded / xhr.total * 100) + "% loaded");
},
// called when loading has errors
function (error) {
console.log("An error happened", error);
}
);
}
// create camera pivot to orbit around center
let cameraHorizontal = new THREE.Object3D();
let cameraVertical = new THREE.Object3D();
let cameraPlaceholder = new THREE.Object3D();
cameraPlaceholder.position.z = 10;
cameraVertical.add(cameraPlaceholder);
cameraVertical.rotation.x = -.2;
cameraHorizontal.add(cameraVertical);
cameraHorizontal.updateMatrixWorld(true);
let camera = new THREE.PerspectiveCamera(75, rect.width/rect.height, 0.1, 1000);
function updateCamera() {
let worldPosition = cameraPlaceholder.getWorldPosition();
camera.position.copy(worldPosition);
let worldQuaternion = cameraPlaceholder.getWorldQuaternion();
camera.setRotationFromQuaternion(worldQuaternion);
camera.updateProjectionMatrix();
}
// create light
let light = new THREE.DirectionalLight(0xffffff, 0.8);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff));
// create water
let waterGeometry = new THREE.PlaneBufferGeometry(10000, 10000);
let water = new THREE.Water(
waterGeometry,
{
textureWidth: 2048,
textureHeight: 2048,
waterNormals: new THREE.TextureLoader().load("https://rawgit.com/mrdoob/three.js/master/examples/textures/waternormals.jpg", function (texture) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
}),
alpha: 0,
sunDirection: light.position.clone().normalize(),
sunColor: 0xffffff,
waterColor: 0x001e0f,
distortionScale: 0,
fog: scene.fog !== undefined
}
);
water.rotation.x = -Math.PI / 2;
water.matrixAutoUpdate = false;
water.rotationAutoUpdate = false;
water.updateMatrix();
scene.add(water);
// create skybox
let sky = new THREE.Sky();
let uniforms = sky.material.uniforms;
uniforms.turbidity.value = 10;
uniforms.rayleigh.value = 2;
uniforms.luminance.value = 1;
uniforms.mieCoefficient.value = 0.005;
uniforms.mieDirectionalG.value = 0.8;
let parameters = {
distance: 400,
inclination: 0.2,
azimuth: 0.205
};
let cubeCamera = new THREE.CubeCamera(0.1, 1, 512);
cubeCamera.renderTarget.texture.generateMipmaps = true;
cubeCamera.renderTarget.texture.minFilter = THREE.LinearMipmapLinearFilter;
scene.background = cubeCamera.renderTarget;
// create renderer
let renderer = new THREE.WebGLRenderer();
renderer.setSize(rect.width, rect.height);
div.appendChild(renderer.domElement);
function updateSun() {
let theta = Math.PI * (parameters.inclination - 0.5);
let phi = 2 * Math.PI * (parameters.azimuth - 0.5);
light.position.x = parameters.distance * Math.cos(phi);
light.position.y = parameters.distance * Math.sin(phi) * Math.sin(theta);
light.position.z = parameters.distance * Math.sin(phi) * Math.cos(theta);
sky.material.uniforms.sunPosition.value = light.position.copy(light.position);
water.material.uniforms.sunDirection.value.copy(light.position).normalize();
cubeCamera.update(renderer, sky);
}
updateSun();
// add event listeners for rotate camera
let movingWith = null;
renderer.domElement.addEventListener("pointerdown", event => {
if (movingWith != null) {
return;
}
event.preventDefault();
movingWith = event.pointerId;
function onmove(event) {
if (event.pointerId !== movingWith) {
return;
}
event.preventDefault();
cameraVertical.rotation.x = Math.max(Math.min(cameraVertical.rotation.x - (event.movementY / 50), -.01), -(Math.PI / 2) + .2);
cameraHorizontal.rotation.y = (cameraHorizontal.rotation.y - (event.movementX / 50)) % (2 * Math.PI);
cameraHorizontal.updateMatrixWorld(true);
}
window.addEventListener("pointermove", onmove);
window.addEventListener("pointerup", function onup() {
if (event.pointerId !== movingWith) {
return;
}
event.preventDefault();
window.removeEventListener("pointermove", onmove);
window.removeEventListener("pointerup", onup);
movingWith = null;
})
});
let lastTime;
let animate = function () {
let now = Date.now();
let deltaTime = (now - lastTime) / 1000;
lastTime = now;
water.material.uniforms.time.value += deltaTime;
updateCamera();
renderer.render(scene, camera);
requestAnimationFrame(animate);
};
lastTime = Date.now();
animate();
// resize canvas with window
window.addEventListener("resize", this._onresize = () => {
let rect = div.getBoundingClientRect();
renderer.setSize(rect.width, rect.height);
camera.aspect = rect.width / rect.height;
camera.updateProjectionMatrix();
});
And Here is the codepen.
Any help is appreciated.
Thanks in advance
Thanks for sharing the codepen. This is actually a bug in Water which should be fixed with the next release R116.
I've update your codepen here with the fix: https://jsfiddle.net/q2cemtb0/1/
Respective PR at GitHub: https://github.com/mrdoob/three.js/pull/19016
I am trying to achieve something like this:
I have a Polyline and its points now I want to create a sheet same as shown in the image. Above is polyline and below a sheet created from that polyline points.
I followed solution from this post Extruding a line in three.js but when I try this it renders nothing.
Here is the code which I tried:
let containerThreeJs = document.getElementById('threed-view-container');
let w = containerThreeJs.offsetWidth;
let h = containerThreeJs.offsetHeight;
let renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(w, h);
containerThreeJs.appendChild(renderer.domElement);
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(5, 1, 1, 1000);
camera.position.setScalar(300);
let threeDpoints = [
[88.5, 370],
[229.5, 268],
[300.5, 333],
[373.5, 290],
[426.5, 392]
];
let geometry = extrudePath(threeDpoints, 100);
var material = new THREE.MeshBasicMaterial({
color: 0x00ff00,
side: THREE.DoubleSide
});
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
render();
function resize(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 (resize(renderer)) {
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function extrudePath(points, depth) {
var geometry = new THREE.PlaneGeometry(10, 10, points.length - 1, 1);
var vertices = geometry.vertices;
// if I comment this loop then the plane is visible
for (var i = 0, l = points.length, p; i < l; i++) {
p = points[i];
vertices[i].x = vertices[i + l].x = p[0];
vertices[i].y = vertices[i + l].y = p[1];
vertices[i].z = p[2];
vertices[i + l].z = p[2] + depth;
}
geometry.computeFaceNormals();
return geometry;
}
<script src="http://mrdoob.github.io/three.js/build/three.min.js"></script>
<script src=http://mrdoob.github.io/three.js/examples/js/controls/OrbitControls.js></script>
<div id="threed-view-container" style="width: 100%; height: 500px"></div>
If I remove the for-loop from extrudePath then the simple plane is visible, but if I keep it nothing seems to render.
I'm not sure, but i see this: In the points array threeDpoints, every point has 2 parts. However in the extrudePath function it's looking for 3. (p[0], p[1], p[2])
`let threeDpoints = [
[88.5, 370],
[229.5, 268],
[300.5, 333],
[373.5, 290],
[426.5, 392]
];
`
`p = points[i];
vertices[i].x = vertices[i + l].x = p[0];
vertices[i].y = vertices[i + l].y = p[1];
vertices[i].z = p[2];
vertices[i + l].z = p[2] + depth;`
i m following this guide for the light Light in Threejs
and i already add some light in my scene.
Now i m try to add a light on the character of my game, but still dont work.
i use the same code of the guide changing just the position.set
const color = 0xFFFFFF;
const intensity = 1;
const light2 = new THREE.SpotLight(color, intensity,0,Math.PI/3);
light2.position.set(100,-5000,1000);
light2.target = lightTarget;
light2.castShadow = true;
const helper2 = new THREE.SpotLightHelper(light2);
and after i add in this way to my character
self.flame.add( helper2 );
self.flame.add(lightTarget);
self.flame.add(light2);
I added a helper too, but if I use just the helper in the scene , so if comment
self.flame.add(light2)
I see the position of the light in perfect way, when add the light the helper disappear (in other light don't happened) and the light go as her want.
Someone can help me?
The helpers have to be parented to the scene (or at least the SpotLightHelper does). You may or may not want to parent the target to the scene.
You also need to call helper.update for each helper
'use strict';
/* global THREE, dat */
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const fov = 45;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 10, 20);
const controls = new THREE.OrbitControls(camera, canvas);
controls.target.set(0, 5, 0);
controls.update();
const scene = new THREE.Scene();
scene.background = new THREE.Color('black');
{
const planeSize = 40;
const loader = new THREE.TextureLoader();
const texture = loader.load('https://threejsfundamentals.org/threejs/resources/images/checker.png');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.magFilter = THREE.NearestFilter;
const repeats = planeSize / 2;
texture.repeat.set(repeats, repeats);
const planeGeo = new THREE.PlaneBufferGeometry(planeSize, planeSize);
const planeMat = new THREE.MeshPhongMaterial({
map: texture,
side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(planeGeo, planeMat);
mesh.rotation.x = Math.PI * -.5;
scene.add(mesh);
}
const cubes = [];
let parent = scene;
{
const cubeSize = 1;
const cubeGeo = new THREE.BoxBufferGeometry(cubeSize, cubeSize, cubeSize);
const cubeMat = new THREE.MeshPhongMaterial({
color: '#8AC',
emissive: '#333',
});
for (let i = 0; i < 6; ++i) {
const mesh = new THREE.Mesh(cubeGeo, cubeMat);
mesh.position.set(1, 0, 0);
parent.add(mesh);
cubes.push(mesh);
parent = mesh;
}
}
cubes[0].position.set(-3, 7, 0);
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.SpotLight(color, intensity);
light.position.set(0, 0, 0);
light.target.position.set(0, -1, 0);
parent.add(light);
parent.add(light.target);
//scene.add(light.target);
const helper = new THREE.SpotLightHelper(light);
scene.add(helper);
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(time) {
time *= 0.001;
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
for (const cube of cubes) {
cube.rotation.z = Math.sin(time) * .4;
}
light.angle = THREE.Math.lerp(
THREE.Math.degToRad(20),
THREE.Math.degToRad(80),
Math.sin(time * 0.77) * 0.5 + 0.5);
helper.update();
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
html, body {
margin: 0;
height: 100%;
}
#c {
width: 100%;
height: 100%;
display: block;
}
<canvas id="c"></canvas>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r105/three.min.js"></script>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r105/js/controls/OrbitControls.js"></script>
Hello I have one doubt:
I have studied:
https://threejs.org/docs/#api/materials/PointsMaterial
And I have adapted the example to work with my existing code.
The aim is to render points on top of the model which we have loaded on click position.
Here we have the code, the important part is onDocumentMouseDown(), the file, logic.js:
if (!Detector.webgl) Detector.addGetWebGLMessage();
// global variables for this scripts
let OriginalImg,
SegmentImg;
var mouse = new THREE.Vector2();
var raycaster = new THREE.Raycaster();
var mousePressed = false;
var clickCount = 0;
init();
animate();
// initilize the page
function init() {
let filename = "models/nrrd/columna01.nrrd"; // change your nrrd file
let idDiv = 'original';
OriginalImg = new InitCanvas(idDiv, filename);
OriginalImg.init();
console.log(OriginalImg);
filename = "models/nrrd/columnasegmentado01.nrrd"; // change your nrrd file
idDiv = 'segment';
SegmentImg = new InitCanvas(idDiv, filename);
SegmentImg.init();
}
let originalCanvas = document.getElementById('original');
originalCanvas.addEventListener('mousedown', onDocumentMouseDown, false);
originalCanvas.addEventListener('mouseup', onDocumentMouseUp, false);
function onDocumentMouseDown(event) {
mousePressed = true;
clickCount++;
mouse.x = ( ( event.clientX - OriginalImg.renderer.domElement.offsetLeft ) / OriginalImg.renderer.domElement.clientWidth ) * 2 - 1;
mouse.y = -( ( event.clientY - OriginalImg.renderer.domElement.offsetTop ) / OriginalImg.renderer.domElement.clientHeight ) * 2 + 1
console.log('Mouse x position is: ', mouse.x, 'the click number was: ', clickCount);
console.log('Mouse Y position is: ', mouse.y);
raycaster.setFromCamera(mouse.clone(), OriginalImg.camera);
var objects = raycaster.intersectObjects(OriginalImg.scene.children);
var pointGeometry = new THREE.Geometry();
var position = new THREE.Vector3();
position.x = objects[0].point.x;
position.y = objects[0].point.y;
position.z = objects[0].point.z;
pointGeometry.vertices.push(position);
var pointMaterial = new THREE.PointsMaterial({color: 0x888888});
var point = new THREE.Points(pointGeometry, pointMaterial);
OriginalImg.scene.add(point);
console.log(objects);
}
function onDocumentMouseUp(event) {
mousePressed = false
}
function animate() {
requestAnimationFrame(animate);
OriginalImg.animate();
SegmentImg.animate();
}
And we do add the points to the scene, but in fact they do not render, they do not show, and I wonder why?:
As you could see in the image we see that the raycaster intercepts those new created points, however the do not get drawn.
I wonder if they are too small, or just the color hides them with the background.
Could you help me please?.
Additional code:
// this class handles the load and the canva for a nrrd
// Using programming based on prototype: https://javascript.info/class
// This class should be improved:
// - Canvas Width and height
InitCanvas = function (IdDiv, Filename) {
this.IdDiv = IdDiv;
this.Filename = Filename
}
InitCanvas.prototype = {
constructor: InitCanvas,
init: function () {
this.container = document.getElementById(this.IdDiv);
// this should be changed.
debugger;
this.container.innerHeight = 600;
this.container.innerWidth = 800;
//These statenments should be changed to improve the image position
this.camera = new THREE.PerspectiveCamera(60, this.container.innerWidth / this.container.innerHeight, 0.01, 1e10);
this.camera.position.z = 300;
let scene = new THREE.Scene();
scene.add(this.camera);
// light
let dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(200, 200, 1000).normalize();
this.camera.add(dirLight);
this.camera.add(dirLight.target);
// read file
let loader = new THREE.NRRDLoader();
loader.load(this.Filename, function (volume) {
//z plane
let sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4));
debugger;
this.container.innerWidth = sliceZ.iLength;
this.container.innerHeight = sliceZ.jLength;
sliceZ.mesh.material.color.setRGB(0,1,1);
console.log('Our slice is: ', sliceZ);
scene.add(sliceZ.mesh);
}.bind(this));
this.scene = scene;
// renderer
this.renderer = new THREE.WebGLRenderer({alpha: true});
this.renderer.setPixelRatio(this.container.devicePixelRatio);
debugger;
this.renderer.setSize(this.container.innerWidth, this.container.innerHeight);
// add canvas in container
this.container.appendChild(this.renderer.domElement);
},
animate: function () {
this.renderer.render(this.scene, this.camera);
}
}
I wonder about the point size because if we see this example they are made with 0.05 of size:
https://github.com/mrdoob/three.js/blob/master/examples/webgl_interactive_raycasting_points.html
And in the example we see the camera being quite far away from the points being generated and they are visible:
https://threejs.org/examples/webgl_interactive_raycasting_points.html
What do you think?
You can use THREE.BufferGeometry() with .setDrawRange():
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(1, 5, 5);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var mesh = new THREE.Mesh(new THREE.SphereBufferGeometry(3, 32, 24), new THREE.MeshBasicMaterial({
wireframe: true,
color: "red"
}));
scene.add(mesh);
var idx = 0;
var maxIdx = 10;
var points = [];
for (let i = 0; i < maxIdx; i++) {
points.push(new THREE.Vector3());
}
var geometry = new THREE.BufferGeometry().setFromPoints(points);
geometry.setDrawRange(0, idx);
var points = new THREE.Points(geometry, new THREE.PointsMaterial({
size: 0.125,
color: "yellow"
}));
scene.add(points);
window.addEventListener("mousemove", onMouseMove, false);
window.addEventListener("mousedown", onMouseDown, false);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects = [];
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function onMouseDown(event) {
raycaster.setFromCamera(mouse, camera);
intersects = raycaster.intersectObject(mesh);
if (intersects.length === 0) return;
if (idx == maxIdx) return;
let p = intersects[0].point;
geometry.attributes.position.setXYZ(idx, p.x, p.y, p.z);
geometry.attributes.position.needsUpdate = true;
idx++;
geometry.setDrawRange(0, idx);
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
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.