ken.mayfield Posted June 6, 2011 Posted June 6, 2011 Is there a Unigine function that will translate world position vec3(x,y,z) to screen position (x,y)? This will be useful to place UI images on/around 3d objects within the world.
manuel.gysin Posted June 6, 2011 Posted June 6, 2011 Is there a Unigine function that will translate world position vec3(x,y,z) to screen position (x,y)? This will be useful to place UI images on/around 3d objects within the world. Sorry misread it. Have a look at this function, there should : vec3 p0,p1; Unigine::getPlayerMouseDirection(p0,p1);
ulf.schroeter Posted June 6, 2011 Posted June 6, 2011 You could use Player::getModelview() and Player::getProjection() functions for manual calculation of combined modelview-projection-matrix for world to screen space transformation. But maybe its much simpler to use ObjectGui instead as it can be attached as child nodes and already provides things like billboarding etc. Have a look at UNIGINE samples_object demo gui_06 (see screenshot). Relevant source code can be found in <UNIGINE-sdk-root>\data\samples\objects\gui_06.cpp.
ken.mayfield Posted June 6, 2011 Author Posted June 6, 2011 I would need the other direction... getting the screen position based on an objects location in 3d space (and without using the mouse).
ken.mayfield Posted June 6, 2011 Author Posted June 6, 2011 Manual math seems like the only option as I need to draw pointers when objects leave the screen as well.
ulf.schroeter Posted June 6, 2011 Posted June 6, 2011 Manual math seems like the only option as I need to draw pointers when objects leave the screen as well. Then maybe engine.visualizer functions might be a usable approach for drawing 3D vectors/lines/text etc. See example with vectors drawn by engine.visualizer.renderVector()
ken.mayfield Posted June 7, 2011 Author Posted June 7, 2011 Doing the math works very well, except Player::getProjection() always returns a mat4 with an apsect ration of 1, so everything is a bit off unless your run your app the same width/height resolution. We got around this by using the perspective() function.
steve3d Posted June 8, 2011 Posted June 8, 2011 it would be nice if engine provided some function to do these kind of jobs.
danni.coy Posted June 21, 2011 Posted June 21, 2011 it would be nice if engine provided some function to do these kind of jobs. agreed this is the class I am using. class ScreenPoint{ vec3 world_position; vec4 screen_position; int floor,optimise; // Object selection; Gui gui; ScreenPoint(vec3 pos,int floor_ = false ,int optimise_ = true) { world_position = pos; floor = floor_; optimise = optimise_; gui = engine.getGui(); } vec4 update(mat4 mvp) { mat4 position = vec4(mat4(world_position).m03m13m23,1.0); screen_position = mvp * position; if(screen_position.w < EPSILON && optimise) return NULL; screen_position /= abs(screen_position.w); screen_position.x = (0.5 + screen_position.x * 0.5) * gui.getWidth(); screen_position.y = (0.5 - screen_position.y * 0.5) * gui.getHeight(); return screen_position; } vec3 getWorldPosition() {return world_position;} void setWorldPosition(vec3 pos=NULL) { if(is_vec3(pos)) {world_position = pos;return;} } vec4 getScreenPosition() {return screen_position;} void setScreenPosition(vec4 pos) {screen_position = pos;} }; where mvp is calculated using mat4 projection = player.getProjection(); projection.m00 *= float(gui.getHeight()) / gui.getWidth(); mat4 mvp = projection * player.getIWorldTransform(); This only needs to be calculated once everytime the camera changes.
frustum Posted July 15, 2011 Posted July 15, 2011 This function will be available in the next SDK. int getScreenPosition(vec3 point,int &x,int &y) { Player player = getPlayer(); if(player == NULL) return 0; int width = engine.app.getWidth(); int height = engine.app.getHeight(); mat4 projection = player.getProjection(); mat4 modelview = player.getIWorldTransform(); projection.m00 *= float(height) / width; vec4 p = projection * (modelview * vec4(point,1.0f)); if(p.w > 0.0f) { x = int(width * (0.5f + p.x * 0.5f / p.w)); y = int(height * (0.5f - p.y * 0.5f / p.w)); return 1; } return 0; }
Recommended Posts