What I’m trying to do is to project a bunch of rays from a node but I don’t want them to be parallel but to go out in a angle (like light coming from a flash-light) and I want to control both the horizontal and vertical angles (also negative angles and parallel lines at 90deg).
I tried using a LensNode, tried some trigonometry but I had little success, something was always wrong. My last attempt was to make a quaternion, set its heading and pitch then get its forward vector, it would be quite elegant and simple… if it worked. I’m not sure if I’m doing something wrong, or if it’s some inherent property of quaternions but the vector I get is just slightly wrong (at least in one plane):
This is how I expect it to look:
(this is from a orographic camera, there are 5 rows and 5 columns of rays, but the rays overlap all nice)
…and this is what I get:
Here is my code:
from panda3d.core import * from direct.showbase import ShowBase from direct.showbase.DirectObject import DirectObject from direct.gui.OnscreenText import OnscreenText # Function to put instructions on the screen. def addInstructions(pos, msg): return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), scale=.05, shadow=(0, 0, 0, 1), parent=base.a2dTopLeft, pos=(0.08, -pos - 0.04), align=TextNode.ALeft) class App(DirectObject): def __init__(self): self.base = ShowBase.ShowBase() #make the camera orthographic self.base.disableMouse() base.camLens=OrthographicLens() film_size=Vec2(base.get_size()) film_size/=film_size/16 #zoom out base.camLens.set_film_size(film_size) base.cam.node().set_lens(base.camLens) #instructions self.inst1 = addInstructions(0.06, "UP ARROW: View from top") self.inst2 = addInstructions(0.12, "RIGHT ARROW: View from side") self.inst3 = addInstructions(0.18, "Current view:") #view from the side self.set_view((-100, 0, 0), (-90, 0, 0), 'side') node=render.attach_new_node('node') rows=5 columns=5 row_offset=0.5 column_offset=0.5 row_angle=30.0 column_angle=15.0 lines= q=Quat() for row in range(rows): for column in range(columns): local_origin=Point3(row*row_offset, 0, column*column_offset) origin=render.get_relative_point(node, local_origin) #scale the angles hpr=(row_angle-row_angle*row/(rows-1)*2.0, -1.0*(column_angle-column_angle*column/(columns-1)*2.0), 0.0) q.set_hpr(hpr) v=q.get_forward()*100.0 #target a point 100.0 units away target=render.get_relative_vector(node, v)+origin lines.append((origin, target)) #draw lines l=LineSegs() for origin, target in lines: l.move_to(origin) l.draw_to(target) line=render.attach_new_node(l.create()) #key binds self.accept('arrow_right', self.set_view, [(-100, 0, 0), (-90, 0, 0), 'side']) self.accept('arrow_up', self.set_view, [(0, 0, 100), (-90, -90, 0), 'top']) def set_view(self, pos, hpr, name): '''Sets the camera hpr and pos andl also display a name''' base.camera.set_pos(pos) base.camera.set_hpr(hpr) self.inst3.destroy() self.inst3 = addInstructions(0.18, "Current view: "+name) #run it app=App() app.base.run()
If someone has any insights how to fix this, or some other idea how to get the same result please do help.