Amerio.Stephane Posted February 1, 2021 Share Posted February 1, 2021 Hello, I have an issue where each WorldIntersection takes between 1 and 2ms each! Context: I created a GroundClamp component that I attach to entities coming from some DIS emitter which has no clue about the terrain. So, the DIS entity received has an altitude and attitude that wouldn't match the terrain. To fix that, the Component makes three WorldIntersection and moves the geometry to clamp the mesh to the terrain. But each WorldIntersection takes so much time that we can't keep the framerate. Note we might have quite a few entities with this component attached. I could of course reduce the frequency of sampling, but still I feel 2ms is far too much for a s ingle intersection. I attached the code for the component too, in case you spot an obvious mistake. Thanks! GroundClampComponent.cpp GroundClampComponent.h Link to comment
silent Posted February 1, 2021 Share Posted February 1, 2021 Hi Stephane, Are you using LandscapeTerrain or ObjectTerrainGlobal? These intersections are for aircraft wheels? Thanks! How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
cash-metall Posted February 1, 2021 Share Posted February 1, 2021 can you send a complete dump file from microprofile (console command microprofile_dump_html) and screenshot of show_profiler 2 information ? also can you test the performance on your scene with this injection ? // GroundClampComponent::init() // ... excluder(node, exclude); if (auto terrain = Plugins::IG::Manager::get()->getTerrain()) exclude.append(terrain); if (auto water = Plugins::IG::Manager::get()->getWater()->getWater()) exclude.append(water); wi = WorldIntersection::create(); // ... Link to comment
Amerio.Stephane Posted February 1, 2021 Author Share Posted February 1, 2021 Here are some data. Notice that inside the worldintersection that takes a lot of time there is a LOT of Sort Field Height Order (don't know what they are). perfs.zip Link to comment
Amerio.Stephane Posted February 1, 2021 Author Share Posted February 1, 2021 (edited) I think I found a bug: If ObjectWaterGlobal is a child of GeodeticPivot and Flat is unchecked, then the intersection with the water is not found! (meaning neither WorldIntersection nor LOS work with a curved GlobalWater) Also, I'm using TerrainGlobal Edited February 1, 2021 by Amerio.Stephane Link to comment
cash-metall Posted February 2, 2021 Share Posted February 2, 2021 how many FieldHeight is in the scene? its look like some problem in curved water. its important to use curved water? if you are using only vertical intersection - you can use water->getHeight() (the same way is used in hat/hot request) //init: float water_offset = water_node->getWorldPosition().z; exclude.append(water_node); // update ///.... Vec3 flat_pos = Vec3(pc.x, pc.y, 0); float water_hight = -UNIIGNE_INFINITY; float intersect_hight = -UNIIGNE_INFINITY; // Intersection with water if (water_node && water_node->isEnabled() && (water_node->getIntersectionMask(0) & intersectionMask.get()) { water_height = water_node->getHeight(flat_pos) + water_offset; //vec3 water_normal = water_node->getNormal(flat_pos); } // intersection with meshes and other objects (water_node in exlude) ObjectPtr o = World::getIntersection(pc + offset, pc - offset, intersectionMask.get(), exclude, wi); if (o) { intersect_hight = wi->getPoint().z; } float res = max(water_height, intersect_hight); pg[i] = pc; pg[i].z = res * (1. - damping.get()) + res * damping.get(); ///... 1 Link to comment
Amerio.Stephane Posted February 2, 2021 Author Share Posted February 2, 2021 There is ZERO Field Height in the scene at the moment (but I'll be adding some to simulate wake waves on boats). A Flat water is OK, I'll go with this as a quick workaround. Thanks for the code sample, I'll try. Link to comment
cash-metall Posted February 3, 2021 Share Posted February 3, 2021 @Amerio.Stephane for round water float water_height = 0.0f; if (water->findAncestor(Node::GEODETIC_PIVOT)) { auto geopos = ig->getConverter()->worldToGeodetic(world_pos); auto basis = ig->getConverter()->getZeroBasis(Vec3(geopos.x, geopos.y, 0)); water_height = water->getHeight(basis.getTranslate()) - basis.getTranslate().z; } else { water_height = water->getHeight(Vec3(world_pos.x, world_pos.y, 0)); } 1 Link to comment
Amerio.Stephane Posted February 3, 2021 Author Share Posted February 3, 2021 Hello, I tried but it doesn't work as expected. There is a vertical error that increase very rapidly the further I am from the geodetic origin. In our vdb, the origin is approx. at 43.46N5.218E. If I place the entity at 43.43N5.18E then the error is approx 10m vertically. Also, while the water->getHeight() itself seem to be very quick, there is a lot of time that is wasted doing ...nothing? the microprofile just shows an empty space between two sampling: The blue "wat" is the profiling of water->getHeight(), and between theme there is almost nothing. The code is attached, along with a boat with our setup so you can double-check. The small brown profiler sample next to the blue "wat" is just a matrix multiplication, and there should be another profiler mark noted "move.." but it doesn't appear! What is going on? So to sum up: I must be missing something to do with the height returned by water->getHeight() to correct for the curvature The perf is still not right (something hidden eat up a lot of time) One of the profiler mark does not show up. Thanks for your help!Components.zip hurricane.zip profiler.zip Link to comment
cash-metall Posted February 4, 2021 Share Posted February 4, 2021 notes about Profiler its better to use beginMicro int id = Profiler::beginMicro("matmul"); // code to be profiled Profiler::endMicro(id); and without unique value in profile header (its too slow, only for debug) Profiler::begin(String::format("move %g %g %g", mg.x, mg.y, mg.z)); // << too slow as for the water increase error - I will check and complete the answer Link to comment
cash-metall Posted February 4, 2021 Share Posted February 4, 2021 @Amerio.Stephane try to use this // init modificate //... water_node = checked_ptr_cast<ObjectWaterGlobal>(World::getNodeByType(Node::OBJECT_WATER_GLOBAL)); pivot = checked_ptr_cast<GeodeticPivot>(World::getNodeByType(Node::GEODETIC_PIVOT)); if (water_node) exclude.append(water_node); water_is_curved = water_node->findAncestor(Node::GEODETIC_PIVOT) != -1; //... //update modificate //... if (water_is_curved) { auto geopos = pivot->toGeodetic(translate(pc)); auto basis = pivot->toWorld(Vec3(geopos.x, geopos.y, 0)); water_height = water_node->getHeight(basis.getTranslate()); } else { water_height = water_node->getHeight(flat_pos); } //.. it takes some mistakes ~1 meter on 100km. and some mistakes with wave detection on high bofort GroundClampComponent.cpp GroundClampComponent.h 1 Link to comment
Amerio.Stephane Posted February 4, 2021 Author Share Posted February 4, 2021 This one works GREAT! So this fixes the user-code issue with water intersection and performance looks good now! There still is the issue with CIGI LOS though, but that will be dealt with in the Support line I guess. Thanks again for the code sample and your commitment! This is really appreciated! 1 Link to comment
Recommended Posts