My objective is: having an arrow in a 2d pos, calc the angle to a 3d object.
I also tried reparenting it to render (wrt), lookAt, reparent to aspect2d back, but it fails (after reparented from 2d to 3d it does NOT keep the same pos although the manual says the cs doesnt matter)!
Are the 3D positions that you’re picking all on a single plane (as in picking positions on a flat “ground” plane)? If so, this approach might work for you.
If not, perhaps try this (or, if you’re using a collision system other that Panda’s built-in system, an equivalent mechanism) instead.
Sorry, it’s not about the ground or clicking on something. I have an arrow and it must point an object’s direction. The arrow is in aspect2d (pos = (.6,-.3), eg) and the object is in render (10,63,8). I need the set the arrow R so it will point to the object.
Ah, my mistake. In that case, it might be better to just get the object’s position in 2D space, perhaps using the “project” method in the Lens class. Note that, according to the API, project returns a value in the range (-1, 1) on both axes, which I believe matches the ranges of render2d.
I think that something like this should work:
(This is untested, so you may find that you end up negating the direction of the “diff” vector (by reversing the order of the subtraction that produces it), swapping the parameters to atan2 or negating one or both parameters to atan2, or some other change that I’m missing.)
# Presume that we've stored the object's position in 3D space in the variable "pos3D",
# and that the arrow's position relative to render2d is stored in the variable
# "arrowPos"; I've found that for an object parented to aspect2d its position
# relative to render2d seems to be available by simply calling
# "myObject.getPos(render2d)", where "myObject" is the name of the object.
pos2D = Point2()
if base.camera.getLens().project(pos3D, pos2D):
# The object was visible, so orient the arrow:
diff = pos2D - arrowPos
angle = math.atan2(diff.z, diff.x)
angleInDegrees = math.degrees(angle)
self.arrow.setR(angleInDegrees)
else:
# The object isn't visible; handle as seems best for your project...
Wait–is this something similar to a fighter-sim using an arrow to indicate direction to an enemy? Are you sure that you want the angle between the arrow and the 3D object, and not between some arbitrary forward-vector (such as the camera’s forward vector) and the 3D object?
In the case of a first-person fighter-sim, I think that you could take the vector between the player’s fighter and the target, project that onto a plane defined by the player’s position and forward- and up- vectors and then normalise that to get a direction vector, which, when put through atan2, should, I think, get you the desired angle for an arrow intended to point at the target.
As to project, note that the method description indicates that the result of using it when the target is outside of the lens’s viewing frustum may not be meaningful.
Hmm… Perhaps you might try converting the screen-position of the arrow into 3D space, find the difference vector between that point and the target, then do as I desribed in my preevious post: project that vector onto the plane defined by the player’s position and orientation, and use atan2 to get the appropriate angle.
Ah, fair enough–given that the arrows are (presumably) on screen and that you know (or can define) the depth of the plane on which the arrows sit, I imagine that extrude should do the job.
(Thinking about it, the new-point returned by extrude should be just what you’re looking for, I imagine.)
(My apologies if I previously over-second-guessed what help would be useful to you. ^^; )