The idea pretty much while extending from some previously mentioned posts on mathematics concerning things like building a falloff for the tool in terms of raising or lowering a given terrain (see the example for computing 2 node cubic spline coefficients in a previous blog post of mine as of not too long ago). It appears that basic and intermediate ogre tutorials provide an excellent foundation for a project such as this. Ogre does also provide some simple interpolating smoothing functions as well, although I am not sure that you could amply customize this relative to other known methods such as the one that I've mentioned, so likely you may want to adapt (as I have done) from another game engine a given package or find a working package for c++ that does this bit math work. Actually Ogre does provide some basic linear algebra functionality as well to do computations...for instance, Ogre::Matrix4, Ogre::Matrix3 and so forth coupled with Ogre::Vector4, and so forth which can be used for Matrix and vector products, or computing the .inverse() of a given matrix.
Adaptation legwork generally comes in the form of the design of the selection tool. For instance, in my case, I decided to use from a given a ray to terrain intercepted point, a bounding of box of dimension 2 * radius on both sides (a square) and then from the bounding planar square, iterate the set of points inside this in determining for a given bounding geometry (in my case a circle) all the points falling inside the given tools falloff radius or 1/2 the length of the square where such points given from the distance of the center of the square are less than such fall off radius. By using a bounding square (box) or geometry, obviously this avoids needless computations through point sets that would certainly fail otherwise. Another selection method adapts intermediate tutorial 4, where one creates a bounding volume and then determines the points of intersections using this (likely one would need to manually handle the actual ray bounding volume query process (if using Ogre 1.9) since WorldTerrainFragments appears to be non functioning for terrain ray query processes. Unfortunately, this also still remains a little bit of greek for me, so I wouldn't be able to describe how methods would be drawn up in detail on this method especially in the way of bounding volumes.
Once having the selected vertices. Two possibilities that I have constructed for such tool, or user configured settings terrain height translation (say, where the user can set the tool to increment with each mouse click in increments either raising or lowering such), or alternately a different method, which approximates other 3d modelers which is allowing the user to while holding the mouse button down control the rate of translation vertically all in one shot until the user depresses the mouse button key. Again for translating points (as adapted from another blog post of mine on this subject matter), one can with a fixed falloff type pre compute on scene loading or at any time when the falloff type is selected pre compute say cspline coefficients between a normalized point set (something like points (0,0) and (1,1)) and then simply normalize the t distance parameter for such point in the given translation fall off range. Normalizing I've found is pretty simple which is to say computing the distance between the two points and then dividing by the overall fall off radii...if you need to invert the normal t parameter you can simply use tparam* = 1-t param so that the center points is actually given to a t param* value of 1 and vice versa the most distant points are at zero (indicate no translated change in elevation at this point). Once having the t param or t param * value then one need simply compute the corresponding fall off position using the cspline coefficient equation, and then having applied a translation scale factor or the amount that a user has selected by raising the elevation of the mouse in a given viewport.
This raises the last remaining obstacle to the problem considered here. Since finding the view port elevation coordinates is another mathematical problem. One could simply grab mouse coordinates but the problem obviously with this is if say grabbing the viewport to mouse pointer ray means that choosing the origin of the ray means that elevation control isn't exactly aligned say to a locked ray intercept position on such terrain, and then finessing the terrain with the mouse cursor active for terrain translation is definitely more cumbersome without projecting the position of the cursor so that it is more finely tuned to a given selected terrain position and all surrounding points.
My thought solution (not implemented as of yet), however, considers this problem by creating a perpendicular plane relative to the camera's active viewport that changes even if the viewport changes orientation relative to a terrain locked coordinate. In this case, we can actually use the original mouse ray and from this select the ray's direction to be of aid here, and from this creating a perpendicular to viewport bounding plane that passes through the locked coordinate terrain point.
So I believe in finishing this problem, one should make use of the coordinate point, and from this take the original viewport ray's direction and rotate this as desired by 90 degrees...a the viewport ray direction I believe is given by a three tuple vector coordinate values , construct a ray from say the locked terrain position (as the ray's origin) and then advance it, arbitrarily as desired in finding another point, or alternately you can setup the math computations (say trig or something else if desired). Another point can similarly be yielded using an alternate 90 degree rotation on the desired coordinate axis from such direction vector with a rotation. Ogre provides as with a lot of game programming interfaces Quaternion computations, or handy way of performing rotations Quaternion algebra (product of rotations here), and then converting this rotation back into a direction vector.
Here's another simple code recipe:
PlaneIntersection::PlaneIntersection(Ogre::Vector3 pos, Ogre::Ray mouseRay){
//Ogre::Ray topLeft = mCamera->getCameraToViewportRay(left, top);
Ogre::Vector3 dirvec = mouseRay.getDirection();
//could use quarternions, but we can get orthogonal vectors, assuming
// local x is in the direction of such vector
// that a z rotation (2d) and a y rotation should yield orthogonal
//vector components.
Ogre::Real sinsq = Ogre::Math::Sin(Ogre::Math::DegreesToRadians(90));
Ogre::Real cossq = Ogre::Math::Cos(Ogre::Math::DegreesToRadians(90));
//Ry = {{cost,0,sint},{0,1,0},{-sint,0,cost}}
Ogre::Matrix3 Roty = Ogre::Matrix3(cossq,0,sinsq,0,1,0,-1*sinsq,0,cossq);
//Rz = {{cost,-sint,0},{sint,cost,0},{0,0,1}}
Ogre::Matrix3 Rotz = Ogre::Matrix3(cossq,-1*sinsq,0,sinsq,cossq,0,0,0,1);
Ogre::Vector3 dirvecy = Roty*dirvec; //rotated on y axis
Ogre::Vector3 dirvecz = Rotz*dirvec; //rotated on z axis
Ogre::Ray rayy = Ogre::Ray(pos,dirvecy);
Ogre::Ray rayz = Ogre::Ray(pos,dirvecz);
Ogre::Vector3 point2 = rayy.getPoint(3);
Ogre::Vector3 point3 = rayz.getPoint(3);
Ogre::Plane tplane = Ogre::Plane(pos, point2, point3); // front plane
std::pair test = mouseRay.intersects(tplane);
std::ostringstream ss;
ctest = test.first;
if (test.first){
ss<<"Distance to intersection: "< Ogre::Real tdist = test.second;
Ogre::Vector3 theight = mouseRay.getPoint(tdist);
cheight = theight;
}
In this case I supplied rotation matrices to a given direction vector, which provided new orthogonal direction vectors in two directions which allow for the construction of a plane that intersects the fixed raise terrain selection point and points from a given arbitrary ray cast in two different orthogonal directions relative to the originating view port mouse ray. In this way the added points aid in constructing a plane which is parallel to the viewport and intersects the desired fixed position.
Adaptation legwork generally comes in the form of the design of the selection tool. For instance, in my case, I decided to use from a given a ray to terrain intercepted point, a bounding of box of dimension 2 * radius on both sides (a square) and then from the bounding planar square, iterate the set of points inside this in determining for a given bounding geometry (in my case a circle) all the points falling inside the given tools falloff radius or 1/2 the length of the square where such points given from the distance of the center of the square are less than such fall off radius. By using a bounding square (box) or geometry, obviously this avoids needless computations through point sets that would certainly fail otherwise. Another selection method adapts intermediate tutorial 4, where one creates a bounding volume and then determines the points of intersections using this (likely one would need to manually handle the actual ray bounding volume query process (if using Ogre 1.9) since WorldTerrainFragments appears to be non functioning for terrain ray query processes. Unfortunately, this also still remains a little bit of greek for me, so I wouldn't be able to describe how methods would be drawn up in detail on this method especially in the way of bounding volumes.
Once having the selected vertices. Two possibilities that I have constructed for such tool, or user configured settings terrain height translation (say, where the user can set the tool to increment with each mouse click in increments either raising or lowering such), or alternately a different method, which approximates other 3d modelers which is allowing the user to while holding the mouse button down control the rate of translation vertically all in one shot until the user depresses the mouse button key. Again for translating points (as adapted from another blog post of mine on this subject matter), one can with a fixed falloff type pre compute on scene loading or at any time when the falloff type is selected pre compute say cspline coefficients between a normalized point set (something like points (0,0) and (1,1)) and then simply normalize the t distance parameter for such point in the given translation fall off range. Normalizing I've found is pretty simple which is to say computing the distance between the two points and then dividing by the overall fall off radii...if you need to invert the normal t parameter you can simply use tparam* = 1-t param so that the center points is actually given to a t param* value of 1 and vice versa the most distant points are at zero (indicate no translated change in elevation at this point). Once having the t param or t param * value then one need simply compute the corresponding fall off position using the cspline coefficient equation, and then having applied a translation scale factor or the amount that a user has selected by raising the elevation of the mouse in a given viewport.
This raises the last remaining obstacle to the problem considered here. Since finding the view port elevation coordinates is another mathematical problem. One could simply grab mouse coordinates but the problem obviously with this is if say grabbing the viewport to mouse pointer ray means that choosing the origin of the ray means that elevation control isn't exactly aligned say to a locked ray intercept position on such terrain, and then finessing the terrain with the mouse cursor active for terrain translation is definitely more cumbersome without projecting the position of the cursor so that it is more finely tuned to a given selected terrain position and all surrounding points.
My thought solution (not implemented as of yet), however, considers this problem by creating a perpendicular plane relative to the camera's active viewport that changes even if the viewport changes orientation relative to a terrain locked coordinate. In this case, we can actually use the original mouse ray and from this select the ray's direction to be of aid here, and from this creating a perpendicular to viewport bounding plane that passes through the locked coordinate terrain point.
So I believe in finishing this problem, one should make use of the coordinate point, and from this take the original viewport ray's direction and rotate this as desired by 90 degrees...a the viewport ray direction I believe is given by a three tuple vector coordinate values , construct a ray from say the locked terrain position (as the ray's origin) and then advance it, arbitrarily as desired in finding another point, or alternately you can setup the math computations (say trig or something else if desired). Another point can similarly be yielded using an alternate 90 degree rotation on the desired coordinate axis from such direction vector with a rotation. Ogre provides as with a lot of game programming interfaces Quaternion computations, or handy way of performing rotations Quaternion algebra (product of rotations here), and then converting this rotation back into a direction vector.
Here's another simple code recipe:
PlaneIntersection::PlaneIntersection(Ogre::Vector3 pos, Ogre::Ray mouseRay){
//Ogre::Ray topLeft = mCamera->getCameraToViewportRay(left, top);
Ogre::Vector3 dirvec = mouseRay.getDirection();
//could use quarternions, but we can get orthogonal vectors, assuming
// local x is in the direction of such vector
// that a z rotation (2d) and a y rotation should yield orthogonal
//vector components.
Ogre::Real sinsq = Ogre::Math::Sin(Ogre::Math::DegreesToRadians(90));
Ogre::Real cossq = Ogre::Math::Cos(Ogre::Math::DegreesToRadians(90));
//Ry = {{cost,0,sint},{0,1,0},{-sint,0,cost}}
Ogre::Matrix3 Roty = Ogre::Matrix3(cossq,0,sinsq,0,1,0,-1*sinsq,0,cossq);
//Rz = {{cost,-sint,0},{sint,cost,0},{0,0,1}}
Ogre::Matrix3 Rotz = Ogre::Matrix3(cossq,-1*sinsq,0,sinsq,cossq,0,0,0,1);
Ogre::Vector3 dirvecy = Roty*dirvec; //rotated on y axis
Ogre::Vector3 dirvecz = Rotz*dirvec; //rotated on z axis
Ogre::Ray rayy = Ogre::Ray(pos,dirvecy);
Ogre::Ray rayz = Ogre::Ray(pos,dirvecz);
Ogre::Vector3 point2 = rayy.getPoint(3);
Ogre::Vector3 point3 = rayz.getPoint(3);
Ogre::Plane tplane = Ogre::Plane(pos, point2, point3); // front plane
std::pair
std::ostringstream ss;
ctest = test.first;
if (test.first){
ss<<"Distance to intersection: "<
Ogre::Vector3 theight = mouseRay.getPoint(tdist);
cheight = theight;
}
In this case I supplied rotation matrices to a given direction vector, which provided new orthogonal direction vectors in two directions which allow for the construction of a plane that intersects the fixed raise terrain selection point and points from a given arbitrary ray cast in two different orthogonal directions relative to the originating view port mouse ray. In this way the added points aid in constructing a plane which is parallel to the viewport and intersects the desired fixed position.
No comments:
Post a Comment