Jump to content

WorldIntersection performance


photo

Recommended Posts

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!

 

WorldIntersection.png

GroundClampComponent.cpp GroundClampComponent.h

Link to comment

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

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 by Amerio.Stephane
Link to comment

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();

///...

 

  • Like 1
Link to comment

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

@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));
}

 

  • Like 1
Link to comment

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:

image.png.26c2f2cb2962cd84b52b5854b437ec4a.png

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:

  1. I must be missing something to do with the height returned by water->getHeight() to correct for the curvature
  2. The perf is still not right (something hidden eat up a lot of time)
  3. One of the profiler mark does not show up.

Thanks for your help!Components.zip

hurricane.zip profiler.zip

Link to comment

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

@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

  • Like 1
Link to comment

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!

  • Like 1
Link to comment
×
×
  • Create New...