Three.js camera position shows three coordinates for 360 video - three.js

I have used a 360 video player, when I change the camera position and prints the value it shows all the three coordinates. Shouldn't it show only 2 coordinates while the third should remain constant.I am printing the Camera.position coordinates in render() function.
<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/211120/orbitControls.js"></script>
TEST
TEST2
<script>
var width = window.innerWidth;
var height = window.innerHeight;
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
var video = document.createElement('video');
video.autoplay = true;
video.src = 'https://streams.kolor.com/streams/833ec36d-b115-43a2-bbf1-aaca49046bab/source.02-720p_HD.mp4';
video.crossOrigin = '';
videoTexture = new THREE.Texture(video);
videoTexture.minFilter = THREE.LinearFilter;
videoTexture.magFilter = THREE.LinearFilter;
videoTexture.format = THREE.RGBFormat;
var scene = new THREE.Scene();
var cubeGeometry = new THREE.SphereGeometry(500, 60, 40);
var sphereMat = new THREE.MeshBasicMaterial({map: videoTexture});
sphereMat.side = THREE.BackSide;
var cube = new THREE.Mesh(cubeGeometry, sphereMat);
scene.add(cube);
var camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 10000);
camera.position.y = 50;
camera.position.z = 100;
//camera.position.set(0,50,100);
scene.add(camera);
var controls = new THREE.OrbitControls( camera);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = false;
controls.maxDistance = 50;
controls.minDistance = 50;
function render() {
if( video.readyState === video.HAVE_ENOUGH_DATA ){
videoTexture.needsUpdate = true;
}
controls.update();
renderer.render(scene, camera);
requestAnimationFrame(render);
console.log("X:"+camera.position.x +"Y:"+camera.position.y+"Z:"+camera.position.z);
}
render();
// test button function
// this does not work
var testButton = document.getElementById('testButton');
testButton.onclick = function ()
{
//camera.lookAt(new THREE.Vector3(50,60,70));
camera.position.y = 50;
camera.position.z = 100;
};
// another test button function
// this does work but then the camera bounces back to what it was looking at before
</script>
</body>
</html>

Related

Three JS: CTM file not loading

Here I tried to load a .ctm file in three JS using CTM Loader. But the CTM file is not getting loaded and the object is not visible in the screen, whereas when I load the js file with geometry properties it gets loaded and the object is visible on the screen. So, when I tried to load a ctm file the object is not visible and when I load a js file with geometry properties the object gets loaded.
I have attached the code below
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var FLOOR = -250;
var container;
var camera, scene, controls;
var renderer;
var mesh;
var textureCube;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(30, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000);
camera.position.set(185, 40, 170);
controls = new THREE.OrbitControls(camera);
controls.maxPolarAngle = Math.PI / 2;
controls.minDistance = 150;
controls.maxDistance = 500;
scene = new THREE.Scene();
scene.background = textureCube;
var light = new THREE.PointLight(0xffffff, 1);
light.position.set(2, 5, 1);
light.position.multiplyScalar(30);
scene.add(light);
var light = new THREE.PointLight(0xffffff, 0.75);
light.position.set(-12, 4.6, 2.4);
light.position.multiplyScalar(30);
scene.add(light);
scene.add(new THREE.AmbientLight(0x050505));
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
renderer.domElement.style.position = "relative";
container.appendChild(renderer.domElement);
renderer.gammaInput = true;
renderer.gammaOutput = true;
window.addEventListener('resize', onWindowResize, false);
window.addEventListener('mousemove', onDocumentMouseMove, false);
var start = Date.now();
var position = new THREE.Vector3(-105, -78, -30);
var scale = new THREE.Vector3(30, 30, 30);
var loader = new THREE.CTMLoader(true);
// loader.loadParts("models/ctm/camaro/camaro.js", function (geometries, materials) {
loader.load("models/ctm/camaro/camaro.ctm", function (geometries, materials) {
for (var i = 0; i < geometries.length; i++) {
var mesh = new THREE.Mesh(geometries[i], materials[i]);
mesh.name = "camaro car"
mesh.position.copy(position);
mesh.scale.copy(scale);
scene.add(mesh);
}
var end = Date.now();
console.log("load time:", end - start, "ms");
}, { useWorker: true });
}
function onWindowResize(event) {
SCREEN_WIDTH = window.innerWidth;
SCREEN_HEIGHT = window.innerHeight;
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
camera.updateProjectionMatrix();
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX);
mouseY = (event.clientY - windowHalfY);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}

set camera relative to point collection

I'm trying to set the camera to be 3 units away from a collection of points I would like this to be relative to the group of points since the points will change later on.
So far I can retrieve x,y,z coordinates from the database and are returned using djangos {{coord_x}} I will have to return the correct length, (I could do this on the python side - len()) for now the database query is limited to 20 rows. These points are brought into three.js using a for loop.
How do I set a camera relative to the objects? Do I need to calculate a bounding box?
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.001, 100000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// allow resizing of the window
window.addEventListener('resize', function()
{
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
});
//Controls
controls = new THREE.OrbitControls(camera, renderer.domElement)
//create the shape
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({color: 0x007654, wireframe: false});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
var numpoints = 20;
var dots = []; //If you want to use for other task
for (var i = 0 ; i < numpoints ; i++) {
var x = "{{coord_x}}";
var y = "{{coord_y}}";
var z = "{{coord_z}}";
// var x = Math.random() * (0 - 1) + 1
// var y = Math.random() * (0 - 1) + 1
// var z = Math.random() * (0 - 1) + 1
var dotGeometry = new THREE.Geometry();
dots.push(dotGeometry);
dotGeometry.vertices.push(new THREE.Vector3(x, y, z));
var dotMaterial = new THREE.PointsMaterial( { size: 3, sizeAttenuation: false, color: 0xFF0000 });
var dot = new THREE.Points( dotGeometry, dotMaterial);
scene.add(dot);
}
camera.position.z = 30
//game logic, allow rotation
var update = function()
{
//cube.rotation.x += 0.00;
//cube.rotation.y += 0.0025;
//dot.rotation.x += 0.00;
//dot.rotation.y += 0.005;
};
// draw scene
var render = function()
{
renderer.render(scene, camera);
};
// run game loop (update, render, repeat)
var GameLoop = function()
{
requestAnimationFrame(GameLoop);
update();
render();
};
GameLoop();
</script>
That's how you can work with THREE.Sphere() object to set the position of your camera:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var geom = new THREE.Geometry();
for (let i = 0; i < 100; i++) {
geom.vertices.push(
new THREE.Vector3(
Math.random() - 0.5,
Math.random() - 0.5,
Math.random() - 0.5
).multiplyScalar(10)
);
}
var points = new THREE.Points(geom, new THREE.PointsMaterial({
size: 0.25,
color: "aqua"
}));
scene.add(points);
var sphere = new THREE.Sphere().setFromPoints(geom.vertices);
console.log(sphere);
camera.position.copy(sphere.center);
camera.position.z += sphere.radius / Math.sin(THREE.Math.degToRad(camera.fov / 2));
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

How to change geometry color with dat.GUI?

I have the following code to render a simple cube. It has dat.GUI controls to change rotation, and I want to add a color changer also. Eventually, I want to have a more complex geometry and want to be able to change the color of more than one element.
$(function(){
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, .1, 500);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xdddddd);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
var axis = new THREE.AxisHelper(10);
scene.add (axis);
var grid = new THREE.GridHelper(50, 5);
var color = new THREE.Color("rgb(255,0,0)");
grid.setColors(color, 0x000000);
scene.add(grid);
var cubeGeometry = new THREE.BoxGeometry(5, 5, 5);
var cubeMaterial = new THREE.MeshLambertMaterial({color:0x80ff});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
var planeGeometry = new THREE.PlaneGeometry(30,30,30);
var planeMaterial = new THREE.MeshLambertMaterial({color:0xffffff});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -.5*Math.PI;
plane.receiveShadow = true;
scene.add(plane);
cube.position.x += 0.001;
cube.position.y = 2.5;
cube.position.z = 2.5;
scene.add(cube);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.castShadow = true;
spotLight.position.set (15,30,50);
scene.add(spotLight);
camera.position.x = 40;
camera.position.y = 40;
camera.position.z = 40;
camera.lookAt(scene.position);
var guiControls = new function(){
this.rotationX = 0.001;
this.rotationY = 0.001;
this.rotationZ = 0.001;
}
var datGUI = new dat.GUI();
datGUI .add(guiControls, 'rotationX', -30*Math.PI/180, 30*Math.PI/180);
datGUI .add(guiControls, 'rotationY', -30*Math.PI/180, 30*Math.PI/180);
datGUI .add(guiControls, 'rotationZ', -30*Math.PI/180, 30*Math.PI/180);
render();
function render() {
cube.rotation.x = guiControls.rotationX;
cube.rotation.y = guiControls.rotationY;
cube.rotation.z = guiControls.rotationZ;
requestAnimationFrame(render);
renderer.render(scene,camera);
}
$("#webGL-container").append(renderer.domElement);
renderer.render(scene,camera);
});
I have been able to add a gui to change color, but I cannot figure out how to bind the gui to the cube color.
var gui = new dat.GUI();
var folder = gui.addFolder('folder');
var params = {};
params.color = [255, 0, 255];
folder.addColor(params, 'color');
You can use dat.GUI to change the color of your cube by using a pattern like this one:
var params = {
color: 0xff00ff
};
var gui = new dat.GUI();
var folder = gui.addFolder( 'MATERIAL' );
folder.addColor( params, 'color' )
.onChange( function() { cube.material.color.set( params.color ); } );
folder.open();
three.js r.92

Three.js recover camera values

When I start the script, camera has starting values. When I will move it and click button to set up startign values it is never same. What values I missed?
The best way, I suppose, it is to look at the example.
I used console.log for debbuging camera values.
HTML:
<button id="buttonTest">
TEST
</button>
Please, move cube before click!
<div id="wrapper">
</div>
JS:
var camera, scene, renderer, geometry, material, mesh;
init();
animate();
function init() {
window.wrapper = document.getElementById('wrapper');
var buttonTest = document.getElementById('buttonTest');
buttonTest.addEventListener('click', function() {
test();
});
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 500;
scene.add(camera);
geometry = new THREE.CubeGeometry(200, 200, 200);
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer({
preserveDrawingBuffer: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color("hsl(193, 50%, 57%)"));
wrapper.appendChild(renderer.domElement);
controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.rotateSpeed = 4.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.1;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
controls.addEventListener( 'change', render );
console.log('camera_default: '+camera.position.x+', '+camera.position.y+', '+camera.position.z);
console.log('quaternion_default: '+camera.quaternion.x+', '+
camera.quaternion.y+', '+camera.quaternion.z+', '+camera.quaternion.w);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
render();
}
function render() {
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
function test() {
// lines below shows actual settings
console.log('camera_now: '+camera.position.x+', '+camera.position.y+', '+camera.position.z);
console.log('quaternion_now: '+camera.quaternion.x+', '+
camera.quaternion.y+', '+camera.quaternion.z+', '+camera.quaternion.w);
window.setTimeout(function() {
// this is recovering camera values like
// it was on the sart of script
// it is not enought, what I missed?
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 500;
camera.quaternion.x = 0.0;
camera.quaternion.y = 0.0;
camera.quaternion.z = 0.0;
camera.quaternion.w = 1.0;
console.log('camera_recover_default: '+camera.position.x+', '+camera.position.y+', '+camera.position.z);
console.log('quaternion_recover_default: '+camera.quaternion.x+', '+
camera.quaternion.y+', '+camera.quaternion.z+', '+camera.quaternion.w);
},1500);
}
I suggest simply doing controls.reset(), it should fix your problems.
replace
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 500;
camera.quaternion.x = 0.0;
camera.quaternion.y = 0.0;
camera.quaternion.z = 0.0;
camera.quaternion.w = 1.0;
with
controls.reset();
Be sure to reset your camera's up vector. When you call camera.lookAt, it uses the up vector to calculate the new rotation matrix, which is then applied as a quaternion.
camera.up.set(0, 1, 0);
Add that after resetting your position/quaterion, and the camera should appear at its starting point.

Three.js: Add different images to each side of cylinder

I am trying to add different image to each face of a cylinder in three.js, basically I want the top, bottom and side to be different images.
This is code where I have added one image which wraps the complete cylinder.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.CylinderGeometry(0.9,1,0.5,32,1, false);
var material = new THREE.MeshPhongMaterial({color: 0xffffff, side:THREE.DoubleSide, map: THREE.ImageUtils.loadTexture('cake-texture-nice-golden-ginger-33420104.jpg')});
var cone = new THREE.Mesh(geometry, material);
scene.add(cone);
var width = window.innerWidth; var height = window.innerHeight; var screenW = window.innerWidth; var screenH = window.innerHeight; /*SCREEN*/ var spdx = 0, spdy = 0; mouseX = 0, mouseY = 0, mouseDown = false; /*MOUSE*/ document.body.addEventListener("mousedown", function(event) { mouseDown = true }, false); document.body.addEventListener("mouseup", function(event) { mouseDown = false }, false); function animate() { spdy = (screenH / 2 - mouseY) / 40; spdx = (screenW / 2 - mouseX) / 40; if (mouseDown){ cone.rotation.x = spdy; cone.rotation.y = spdx; } requestAnimationFrame( animate ); render(); } // create a point light var pointLight = new THREE.PointLight( 0xFFFF8F ); // set its position pointLight.position.x = 10; pointLight.position.y = 50; pointLight.position.z = 130; // add to the scene scene.add(pointLight); camera.position.z = 5; var render = function () { requestAnimationFrame(render); //cone.rotation.x += 0.01; //cone.rotation.y += 0.001; //cone.rotation.z -= 0.02; window.addEventListener('mousemove', function (e) { var mouseX = ( e.clientX - width / 2 ); var mouseY = ( e.clientY - height / 2 ); cone.rotation.x = mouseY * 0.005; cone.rotation.y = mouseX * 0.005; cone.rotation.y += mouseY; //console.log(mouseY); }, false); renderer.render(scene, camera); }; render();
This is the pen for the cylinder: http://codepen.io/dilipmerani/pen/XmWNdV
Update-25Sep
var materialTop = new THREE.MeshPhongMaterial({color: 0xffffff, side:THREE.DoubleSide, map: THREE.ImageUtils.loadTexture('chocolate_brown_painted_textured_wall_tileable.jpg')});
var materialSide = new THREE.MeshPhongMaterial({color: 0xffffff, side:THREE.DoubleSide, map: THREE.ImageUtils.loadTexture('cake-texture-nice-golden-ginger-33420104.jpg')});
var materialBottom = new THREE.MeshPhongMaterial({color: 0xffffff, side:THREE.DoubleSide, map: THREE.ImageUtils.loadTexture('cake-texture-nice-golden-ginger-33420104.jpg')});
var materialsArray = [];
materialsArray.push(materialTop); //materialindex = 0
materialsArray.push(materialSide); // materialindex = 1
materialsArray.push(materialBottom); // materialindex = 2
var material = new THREE.MeshFaceMaterial(materialsArray);
var geometry = new THREE.CylinderGeometry(0.9,1,0.5,3,1, false);
var aFaces = geometry.faces.length;
console.log(aFaces);
for(var i=0;i<aFaces;i++) {
geometry.faces[i].materialindex;
}
var cone = new THREE.Mesh(geometry, material);
scene.add(cone);
Thanks
Create MeshFaceMaterial:
var materialTop = new THREE.MeshPhongMaterial(...);
var materialSide = new THREE.MeshPhongMaterial(...);
var materialBottom = new THREE.MeshPhongMaterial(...);
var materialsArray = [];
materialsArray.push(materialTop); //materialindex = 0
materialsArray.push(materialSide); // materialindex = 1
materialsArray.push(materialBottom); // materialindex = 2
var material = new THREE.MeshFaceMaterial(materialsArray);
Update geometry:
var geometry = new THREE.CylinderGeometry(0.9,1,0.5,32,1, false);
faces you can get from geometry.faces
Loop faces and change materialindex: geometry.faces[faceIndex].materialindex
Print geometry.faces to console and check what it has.
var aFaces = geometry.faces.length;
for(var i=0;i<aFaces;i++) {
if(i < 64){
geometry.faces[i].materialIndex = 0;
}else if(i > 63 && i < 96){
geometry.faces[i].materialIndex = 1;
}else{
geometry.faces[i].materialIndex = 2;
}
}
Build your cone
var cone = new THREE.Mesh(geometry, material);
Example of your updated code
You should create faces in mesh's geometry with some materialindex. So you'll have 3 surfaces. And than use MeshFaceMaterial(array of material for each surface).

Resources