I am trying to get infinite zoom functionality,
While looking at the following three.js example:
http://threejs.org/examples/misc_controls_orbit.html
While getting closer to the target vector, the zoom factor reduced and reduced until it barely worked, for an end user it looks like it is stuck. panning won't really work, and in order to zoom out user needs to use the mouse wheel for like ages.
Is there a way to get infinite zoom functionality?
Thanks.
as mentioned it is zooming infinitely ( but it's zooming infinitely to the target at the center of the scene so it will never pass the target and thus never zoom beyond the center of the scene ), there's a couple changes you can make to the controls object in order to render the desired effect ( if I'm understanding you correctly ).
one small change you can make is change the target location from the center of the scene to the other end of the scene, given the the camera's far perameter is set to 1000 we can try setting the target's z position to -1000 in your init() function like so:
controls.target = new THREE.Vector3(0,0,-1000);
here's a working fiddle: http://jsfiddle.net/6gn7k0m4/
in that example you'll zoom past the scene and slow down when you get to -1000. Another approach might be to change the dollyIn and dollyOut methods so that rather than getting infinitely closer to the target what it does is change the camera's z index, this way when you zoom past the target the camera will still rotate around the center, you can do something like this
controls.dollyOut = function(){
this.object.position.z -= 100;
}
controls.dollyIn = function(){
this.object.position.z += 100;
}
here's a working fiddle for that example: http://jsfiddle.net/6gn7k0m4/1/
Related
So I have the basic setup of a three.js-canvas rendered inside of a html-div. Inside the 3d-world I want to position an object in such a way that it appears to be glued on to this outside div (should never move in any way). Currently I have this solution:
render {
object.position.x = camera.position.x;
object.position.y = camera.position.y;
object.position.z = camera.position.z - 200;
}
This works for panning the camera (i have rotation disabled since i don't need it). However, once I zoom in or out it obviously doesn't work any more, since zooming doesn't change the camera's position values. My approach was to incorporate the camera.zoom factor into the above function, but i couldn't get it to work properly. Is there an easy transformation function or something i can use?
Edit: I created a jsfiddle, hopefully this helps figuring out the solution. As long as you pan the camera with right mouse the yellow plane doesn't move at all (wanted behaviour). When you zoom in or out it starts to move (unwanted behaviour): https://jsfiddle.net/rdyLp7uc/2/
I am developing a standard panorama viewer, where a 360 picture is placed inside of a sphere and the user can look around using mouse and touch. I am using OrbtialControls for this and it is working fine.
The user can also load a new 360 picture, after loading the picture, I am trying to set the camera direction so that the user is looking in a certain direction. As I am using orbitalControls, I am using control.target.set(x,y,z) to do so. However that causes the camera to lock at that point and if I use the mouse or touch to look around, the camera position changes and it revolves around that point, rather than looking around inside the sphere.
Has anyone else seen this kind of behavior? Do I need to do something
The code is pretty simple.
controls.reset();
controls.target.set(window.newLookAt.x,window.newLookAt.y,window.newLookAt.z);
The purpose of controls.target.set(x,y,z) is to set the pivot point, so what you are facing is the expected behavior
Instead of setting the target (that has to be (0, 0, 0) in your case), why not putting the camera inside a THREE.Object3D and rotate this object
var camera = new THREE.PerspectiveCamera()
var container = new THREE.Object3D()
container.add( camera )
camera.position.set( 0, 0, 0.1 )
var controls = new THREE.OrbitControls( camera, renderer )
controls.target.set( 0, 0, 0 ) // Optional
container.rotate.y = Math.PI / 2 // Or whatever you want
So I ended up solving this myself. The issue was that my understanding of orbitControls was slightly off. All I needed to do was to set the target point in the same direction but way closer to the camera and presto, issue solved and things are working fine now.
As a precision I already noticed threads about this but didn't find a way to achieve exactly what I need.
Basicaly I have a board of objects that I need remaining always on top of everything but also attached to the camera.
I first tried to add the group to the camera and it stayed as wished always in the viewport. But in this configuration the group of objects still be a part of the scene so while zooming to regular objects in the "editor" the board goes into/among these objects of the scene.
My second trial was based on this thread and work wonderfully in order to get all of the board objects rendered above everything. But on such a configuration when rotating around the axis (with orbit control) both scenes rotates. So I tried to update the foreground scene with coordinates of the camera but the update was not immediate and this scene is flickering (I suppose that while rotating the update function is not called immediately).
My best wish would have been to "attach" the foreground scene to the camera so that it would stay on top and sticked on the screen/viewport but I don't even know if it is possible and how to do that (as only groups of objects seem to be capable to be attached to the camera).
I am really stuck on that point. Thanks you for any help!
If this is what you need,
just set object.material.depthTest = false; and object.renderOrder = 1000; for all objects you need to be always on top and attached to the camera.
i am trying to use the combined camera (found it under "Examples").
the problem is when i use it in Orthographic mode i still see the arrow and the box helper like in perspective view.
for example, when i am trying to zoom in with the mouse scroll, i can see the plane in the same size (as it supposed to be in orthographic view) but the arrows and the small box between the arrows is getting smaller or bigger.
when i tried to debug it at the renderer function i saw the camera is still in orthograpic mode when it render the arrows.
any idea how can i make all the object to be in orthograpic view but still use the combined camera?
edit:
i am not sure which part of the code i should post so i add a picture to describe my problem.
you can see that i am in an orthographic camera and i'm trying to zoom in and i can see the axis arrow getting bigger or smaller.
the difference between the plane when zooming
Found a possible answer which worked for me:
under TransformControls.js
change the update function to:
scale = (camera.inOrthographicMode == true)? 100 : worldPosition.distanceTo(camPosition ) / 6 * scope.size;
I've been working with Jason Davies' Rotate the World and World Countries examples and incorporating a few other bits and pieces to learn about d3.
An example of what I have come up with so far is here.
The small selector in the top left corner will trigger a new 'trip' to be displayed on the globe and the centroid of the trip will be centered in view. This all works well, as does panning and zooming on the globe with the mouse.
However, there's an issue with the present implementation when one zooms in/out, alters the visible trip, then attempts to pan/zoom again: the zoom defaults back to the level it was before the trip change - resulting in a zoom 'jump' I'd like to remove [To see this behaviour, load my MNWE, zoom in with the mouse wheel perhaps 3 times, click the OK button to load 'J07', click on the globe holding the mouse button down and pan a bit - you'll see the jump I'm referring to.].
I'm pretty sure it's just me not updating the scale of my projection correctly, but I don't know enough to troubleshoot further. Jason has implemented a d3.geo.zoom function, which probably should be capable of fixing the issue. My attempt was to call it in my $("#sub").on("click" ... call via:
d3.select("#map").call(d3.geo.zoom().projection(proj).scale(a/2-10).on("zoom.redraw", function() {
d3.select(this).selectAll("path").attr("d", d3.geo.path().projection(proj));
}));
but that gave spurious results after the fact as well.
Lines 344 and 346:
var sc = d3.interpolate(proj.scale(), a / 2 - 10); //344
return function(i) {
proj.rotate(interp(i)).scale(sc(i)); //346
d3.select("#map").selectAll("path").attr("d", d3.geo.path().projection(proj));
//r.world();
};
are probably where I introduce the bug, as the rotation portion works without issue, it's only the scale additions that cause problems.
This can be solved by defining the zoom behavior in global scope.
m = d3.behavior.zoom();
Then update the zoom behavior with the scale in the transition as shown below this will stop the jump effect you have.
d3.transition().delay(250).duration(2250)
.tween("rotate", function() {
interp.source(proj.rotate()).target(coords).distance();
var sc = d3.interpolate(proj.scale(), a / 2 - 10);
return function(i) {
proj.rotate(interp(i)).scale(sc(i));
m.scale(sc(i));//update the zoom in the zoom behavior this will sop the jumping effect
d3.select("#map").selectAll("path").attr("d", d3.geo.path().projection(proj));
//r.world();
};
});
Working code here
Hope this helps.