protected void projectGunSight(int x, int y) {
if(null != gunSight) {
gunSight.setConstraintX(SizeValue.px(x - gunSight.getWidth() / 2));
gunSight.setConstraintY(SizeValue.px(y - gunSight.getHeight() / 2));
gunSight.getParent().layoutElements();
}
}
}
[/java]
with this code, if im facing opposite direction from target, gunsight thinks target is in front of him, only with z greater than 1. i would expect that if im facing back then my crosshair will be at either side of the screen, but not in the middle…
can anyone give me help, how to handle target at the back? i tried some weird stuff like
[java]
if(null != target) {
Vector3f enemyPosProjected = cam.getScreenCoordinates(target.getWorldTranslation());
System.out.println("enemyPosProjected " + enemyPosProjected);
int wHalf = settings.getWidth() / 2;
int hHalf = settings.getHeight() / 2;
int x = 0;
int y = 0;
if(enemyPosProjected.z > 1) {
enemyPosProjected.x = enemyPosProjected.x > wHalf ? enemyPosProjected.x + wHalf : enemyPosProjected.x - wHalf;
enemyPosProjected.y = enemyPosProjected.y > hHalf ? enemyPosProjected.y + hHalf : enemyPosProjected.y - hHalf;
x = (int)enemyPosProjected.x - gunSight.getWidth() / 2;
y = settings.getHeight() - (int)enemyPosProjected.y - gunSight.getHeight() / 2;
} else {
x = (int)enemyPosProjected.x - gunSight.getWidth() / 2;
y = settings.getHeight() - (int)enemyPosProjected.y - gunSight.getHeight() / 2;
}
projectGunSight(x, y);
}
[/java]
but this is as wretched as it looks… i dont know how to handle back targeting hemisphere
The thing you ask by invoking the command is “Where does a line that crosses the cam location and the location of the object cross the screen plane?” If the object is right behind you that line still crosses the screen plane in the center.
ahaa, so it have two correct results, i now understand why this happens. so this is not what i want.
i see some similarity with ray cast, only difference is that ray have origin, so it doesnt go backward and dont hit enemies behind. if ray will be defined by two points as infinite line, it will hit enemies in the front and also back
so my question can be something like how target marks in fps games are made and how can this be done with jme3 ? so if target is behind player slightly to the left, mark will be on one side of the screen and if target is slightly to the right, mark will be on opposite side of the screen
how can i “limit” that line to be only on one side ?
and im stupid enough i cannot formulate question for google how to program target marking, it returning me tons of useless results it bothers me with tons of useless marketing topics
yea google cannot understand me because noone understands me
if enemy is in front of me, it works well
if enemy is behind, it looks like he is in front of me. i tried to glue crosshair to the side when enemy is behind me, but unsuccessfuly…
so trouble is when z > 1
next problem is when enemy is on the plane that cuts front and back “hemisphere”, so at about 90° angle ± some decimals, my crosshair is on the side, which is correct, but also it is forced to be in the upper or lower corner, which is bad.
i simply want crosshair to be in the line of sight everytime, clamped to the visible screen coordinates of course, so absolutly common thing what every game with some targeting system have, for example exactly like sturmovik have those red marks on the sides
im thinking about some orthogonal quad 1wu distant from camera, orbiting that camera and clamped into camera’s frustum
Yes, I kind of understood what you wanted… but short of writing “all the code” for you… I thought I’d ask which part was giving you issues. I’m still not sure.
It’s not really about clamping unless the object is actually of the sides of the screen (and then of course you want to clamp)… otherwise, you just project the vector out to the edge of the screen. Is that what’s giving you issues?
#1
i try to keep things simple i dont want written code, but some tips how can i theoretically do it
@pspeed said:
If it is behind you, figure out if it is to the left or right and indicate accordingly on the edge of the screen.
this is the problem :) and i failed yesterday doing this
so from your text, you suggesting me simply to detect if enemy is on my right or left side and then simply move marker accordingly to the side of the screen. i also thought about this but failed
#2
is big overkill this idea?
create a node “targeting” on rootnode by camera.getlocation, then use targeting.lookat(target.getworldtranslation), then clamp rotation to view angle of camera (i must discover how to do this), then move node forward by 1wu, then use cam.getscreencoordinates on targeting rather than on target… so node targeting will never be on camera’s back
For objects that are behind the camera, invert the y position of the screen coordinate and fix the x position to the side of the screen depending on its x position being on the right half of the screen (fix to left) or the lest half of the screen (fix to right).
thanks normen, i did it as you suggested and when im backwards, crosshair are roughly accurate, but one problem persists, when im at 90° angle, its like hyperbola, but both sides are going up when approacing 0
i dont know how to correct this
Well given the explanation I gave about the result of the method thats normal, the line will never cross the screen plane. You will either have to simply handle these situations in your code or make a similar calculation yourself.
so i came with this solution, its doing about 40-60% of what i want, its pain to look at, so if anyone is interested…
it is done by using two independent nodes (not attached to rootnode). base node have rotation and location same as camera, child node is looking at targets, then limiting rotation of child node to cam.getFrustumXxx methods (those seems to be radians)