songtao.han Posted October 31, 2018 Share Posted October 31, 2018 Hi, I want to make a node snap to the terrain surface while moving it at runtime. It is like the result of "Snap to Surface" button in the editor. But I don't how to do it with C++ APIs. Link to comment
fox Posted October 31, 2018 Share Posted October 31, 2018 Hi songtao.han, World::getIntersection() is what you need in this case Suppose you have a GlobalTerrain object on your scene and some node that you'd like to snap to the terrain's surface. You can use the following function for snapping(call it each frame in the update()): void doIntersection(ObjectTerrainGlobalPtr terrain, NodePtr node) { //Get mouse direction Vec3 p0, p1; int width = App::get()->getWidth(); int height = App::get()->getHeight(); // get the current X and Y coordinates of the mouse pointer int mouse_x = App::get()->getMouseX(); int mouse_y = App::get()->getMouseY(); // get the mouse direction from the player's position (p0) to the mouse cursor pointer (p1) Game::get()->getPlayer()->getDirectionFromScreen(p0, p1, mouse_x, mouse_y, width, height); //Only 10km intersection p1 = p0 + normalize(p1 - p0) * 10000; int is_intersection; WorldIntersectionPtr intersection = WorldIntersection::create(); ObjectPtr object = World::get()->getIntersection(p0, p1, 1, intersection); //Check if there was intersection with the landscape and change node position if (object == terrain->getObject()) { Vec3 point = intersection->getPoint(); point.z += node->getWorldBoundSphere().getRadius(); node->setWorldPosition(point); } } For more information on intersections please refer to this article. Thank you! Link to comment
songtao.han Posted November 5, 2018 Author Share Posted November 5, 2018 On 10/31/2018 at 5:03 PM, fox said: Hi songtao.han, World::getIntersection() is what you need in this case Suppose you have a GlobalTerrain object on your scene and some node that you'd like to snap to the terrain's surface. You can use the following function for snapping(call it each frame in the update()): void doIntersection(ObjectTerrainGlobalPtr terrain, NodePtr node) { //Get mouse direction Vec3 p0, p1; int width = App::get()->getWidth(); int height = App::get()->getHeight(); // get the current X and Y coordinates of the mouse pointer int mouse_x = App::get()->getMouseX(); int mouse_y = App::get()->getMouseY(); // get the mouse direction from the player's position (p0) to the mouse cursor pointer (p1) Game::get()->getPlayer()->getDirectionFromScreen(p0, p1, mouse_x, mouse_y, width, height); //Only 10km intersection p1 = p0 + normalize(p1 - p0) * 10000; int is_intersection; WorldIntersectionPtr intersection = WorldIntersection::create(); ObjectPtr object = World::get()->getIntersection(p0, p1, 1, intersection); //Check if there was intersection with the landscape and change node position if (object == terrain->getObject()) { Vec3 point = intersection->getPoint(); point.z += node->getWorldBoundSphere().getRadius(); node->setWorldPosition(point); } } For more information on intersections please refer to this article. Thank you! Sorry for the delay! But this isn't what I want. I need not only to place a node on the terrain surface but also to change it's orientation automatically by the terrain's hypsography. Shown in the picture below: Link to comment
fox Posted November 6, 2018 Share Posted November 6, 2018 Hi Songtao, I see, in this case you'll need information about the normal at the intersection point to change your node's orientation. You can use the World::getIntersection() method that uses an instance of the WorldIntersectionNormal class to store intersection info. // create an instance of the WorldIntersectionNormal class to get the result WorldIntersectionNormalPtr intersection = WorldIntersectionNormal::create(); // create an instance for intersected object and check the intersection ObjectPtr object = World::get()->getIntersection(p0,p1,1,intersection); // if the intersection has been occurred, change the parameter of the object's material if(object) { // show intersection details in console Log::message("Normal: type %s coordinates (%f %f %f)\n", typeid(intersection->getNormal()).name(), intersection->getNormal().x, intersection->getNormal().y, intersection->getNormal().z); Log::message("Point: (%f %f %f) index: %i \n", intersection->getPoint().x, intersection->getPoint().y, intersection->getPoint().z, intersection->getIndex()); } } Then you can use it to get information about the intersection point and normal to orient your node properly. Thank you! Link to comment
songtao.han Posted November 6, 2018 Author Share Posted November 6, 2018 3 hours ago, fox said: Hi Songtao, I see, in this case you'll need information about the normal at the intersection point to change your node's orientation. You can use the World::getIntersection() method that uses an instance of the WorldIntersectionNormal class to store intersection info. // create an instance of the WorldIntersectionNormal class to get the result WorldIntersectionNormalPtr intersection = WorldIntersectionNormal::create(); // create an instance for intersected object and check the intersection ObjectPtr object = World::get()->getIntersection(p0,p1,1,intersection); // if the intersection has been occurred, change the parameter of the object's material if(object) { // show intersection details in console Log::message("Normal: type %s coordinates (%f %f %f)\n", typeid(intersection->getNormal()).name(), intersection->getNormal().x, intersection->getNormal().y, intersection->getNormal().z); Log::message("Point: (%f %f %f) index: %i \n", intersection->getPoint().x, intersection->getPoint().y, intersection->getPoint().z, intersection->getIndex()); } } Then you can use it to get information about the intersection point and normal to orient your node properly. Thank you! I know I need to get information about the normal at the intersection point. But I don't know how to change the node's orientation using that. Sorry for the stupid question! Link to comment
Greg.Mildenhall Posted November 6, 2018 Share Posted November 6, 2018 Use setWorldTransform() to set the orientation. Link to comment
Recommended Posts