steve3d Posted October 8, 2010 Share Posted October 8, 2010 I've saw there is a function mat4 frustum(float left,float right,float bottom,float top,float znear,float zfar); to convert frustum data to a projection matrix, but how can I get the frustum data from a porjection matrix? Link to comment
steve3d Posted October 8, 2010 Author Share Posted October 8, 2010 or, how to get the frustum data from a Player class? I just can't figure out the top/bottom/right/left how to calculate this? Link to comment
alexei.garbuzenko Posted October 8, 2010 Share Posted October 8, 2010 Player player = engine.game.getPlayer(); mat4 projection = player.getProjection(); projection.m00 *= float(engine.app.getHeight()) / engine.app.getWidth(); mat4 modelview = player.getOffset() * player.getModelview(); Those two matrices represent view frustum that is used in render pipeline. I.e. you could use this code to get all visible objects: Node objects[0]; engine.world.getIntersectionObjects(projection, modelview, objects); P.S. Using this code to hide invisible objects in scene samples/stress/clutter_00 gives huge performance boost meaning of relatively weak spatial tree implementation for such scenes. Link to comment
steve3d Posted October 8, 2010 Author Share Posted October 8, 2010 eh... I think my question is not clear. I mean, how to calculate the value of top/bottom/left/right of a existing player. :( Link to comment
alexei.garbuzenko Posted October 8, 2010 Share Posted October 8, 2010 Well, I'd suggest you to look at the source code: engine\math\MathLib.cpp, method: mat4 frustum(float l,float r,float b,float t,float n,float f); If you don't have a source, just ask engine crew to post this method. Link to comment
steve3d Posted October 10, 2010 Author Share Posted October 10, 2010 well, i've checked the source, but reverse calculate multple value from mulitple variables, seems little difficult. :( :blink: I think there must be another way to calculate the left/right/top/bottom value from near/far/fov/aspect. but how? Link to comment
Guest extaliones Posted October 11, 2010 Share Posted October 11, 2010 The parameters (l, r, b, t, n, f) determine the view frustum of the camera. mat4 frustum(float l,float r,float b,float t,float n,float f) { mat4 ret; float rl = r - l; float tb = t - b; float fn = f - n; ret.m00 = 2.0f * n / rl; ret.m01 = 0.0f; ret.m02 = (r + l) / rl; ret.m03 = 0.0f; ret.m10 = 0.0f; ret.m11 = 2.0f * n / tb; ret.m12 = (t + :( / tb; ret.m13 = 0.0f; ret.m20 = 0.0f; ret.m21 = 0.0f; ret.m22 = -(f + n) / fn; ret.m23 = -2.0f * f * n / fn; ret.m30 = 0.0f; ret.m31 = 0.0f; ret.m32 = -1.0f; ret.m33 = 0.0f; return ret; } The horizontal field of view is determined by the angle between the left and the right planes (determined by l and r) of the frustum. In the same manner, the vertical field of view is determined by the angle between the top and the bottom planes (determined by t and b ). So the view frustum matrix is more common matrix for performing projection expressed in terms of the six-tuple(l, r, b, t, n, f), The perspective matrix expressed in terms (fov, aspect, n, f) created from frustum matrix by r = -l and t = -b. mat4 perspective(float fov,float aspect,float n,float f) { mat4 ret; float h = 1.0f; float w = aspect; if(!compare(fov,90.0f)) { h = Math::tanf(fov * DEG2RAD * 0.5f); w = h * aspect; } float fn = f - n; ret.m00 = 1.0f / w; ret.m01 = 0.0f; ret.m02 = 0.0f; ret.m03 = 0.0f; ret.m10 = 0.0f; ret.m11 = 1.0f / h; ret.m12 = 0.0f; ret.m13 = 0.0f; ret.m20 = 0.0f; ret.m21 = 0.0f; ret.m22 = -(f + n) / fn; ret.m23 = -2.0f * f * n / fn; ret.m30 = 0.0f; ret.m31 = 0.0f; ret.m32 = -1.0f; ret.m33 = 0.0f; return ret; } From player you can get the perspective matrix, z near and f near, so you can find l , r , b , t, solving a simple equations taking into account the equality of the relevant matrix members. Link to comment
steve3d Posted October 11, 2010 Author Share Posted October 11, 2010 well, finally I've got this: float fov = org.getFov(); float ymax = n * tan(fov*PI/360.0); float ymin = - ymax; float xmin = ymin * aspect; float xmax = ymax *aspect ; mat4 proj = frustum(xmin, xmax, ymin, ymax, n, f); I've looked the unigine's player class, it seems the player class always use 1.0 as aspect, so it comes with above code. I've tested this with two PlayerDummy, the second player using projection matrix calculated by the frustum function, it looks exactly same as the first. no matter I change fov/near/far value of first player, the second player is always same. ( at least the visualizer draws the same cone) Link to comment
Guest extaliones Posted October 12, 2010 Share Posted October 12, 2010 Two players (cameras) are independent from each other. So if you changed the parameters of first player it will not affect second player. Link to comment
Recommended Posts