jupyter-widgets / pythreejs

A Jupyter - Three.js bridge
https://pythreejs.readthedocs.io
Other
951 stars 188 forks source link

Picker for Orthographic Camera #101

Closed chrisjsewell closed 6 years ago

chrisjsewell commented 7 years ago

I believe that, if the camera is orthographic, then a pickingRay, rather that Raycaster needs to be used (see https://stackoverflow.com/questions/20361776/orthographic-camera-and-pickingray). Or there is a discussion here that may be of relevance mrdoob/three.js#599

Would love to try myself, but I have no experience in JS and I can't get the devlopment version to work :(

Here is my minimal use case, which does not work for orthographic (the picker only selects the closest object to the camera, irrespective of mouse position):

from pythreejs import *
import ipywidgets as widget
from IPython.display import display

perspective = False
container = Mesh(geometry=Geometry(), 
               material=BasicMaterial(),
               position=[0, 0, 0])

ball1 = Mesh(geometry=SphereGeometry(radius=1), 
                                    material=LambertMaterial(color='red'),
                                    position=[-.5, 0, 1])
ball2 = Mesh(geometry=SphereGeometry(radius=1), 
                                    material=LambertMaterial(color='blue'),
                                    position=[.5, 0, 0])
container.children=[ball1,ball2]

scene = Scene(children=[container, AmbientLight(color='#777777')])

if perspective:
    c = PerspectiveCamera(position=[0, 0, 10], up=[0, 0, 1],aspect=1.0)
else:
    c = OrthographicCamera(position=[0, 0, 10], up=[0, 0, 1],
                          left=-2,right=2,top=2,bottom=-2,near=.1,far=1000)

c.children=[DirectionalLight(color='white',
                position=[3, 5, 1],intensity=0.5)]
renderer = Renderer(camera=c, width='300',height='300',
                    scene=scene, 
                    controls=[OrbitControls(controlling=c)])

click_picker = Picker(root=scene.children[0], event='mousemove')
infobox = widget.HTML()
def change_info(change):
    infobox.value = 'Color: {}'.format(click_picker.object.material.color)
click_picker.observe(change_info, names=['object'])

renderer.controls = renderer.controls + [click_picker]

display(infobox)
display(renderer)
vidartf commented 6 years ago

@chrisjsewell As far as I can tell, that problem is no longer relevant: Three.js now supports OrthographicCamera for the Raycaster, and current master of Pythreejs should support it as well. Let me know if this sounds reasonable to you, or if I have missed something!