Entities far from the origin: view shaking and bad precision

When the entities are very far from the origin their appearance on screen may become very compromised, and the camera may shake badly when moving/rotating the view.

See the image below of a circle created at (1e9, 1e9, 0) with radius 200:

Capture.PNG

This is due to the float precision of OpenGL that isn't enough to represent coordinates very far from the origin.

To fix this issue you need to:

1) Translate the entities back to the origin, put them into a block and add a BlockReference that refers to that block.

2) Translate the BlockReference back to the original position far from the origin.

3) Set the viewportLayout.RemoveJittering property to true.

 

var myMesh = Mesh.CreatePlanar(new Circle(1e9, 1e9, 0, 200), 0.1, meshNatureType.Plain); 
             
myMesh.Translate(-1e9, -1e9, 0); 
myMesh.ColorMethod = colorMethodType.byParent; 

Block myBlock = new Block(); 
myBlock.Entities.Add(myMesh); 
viewportLayout.Blocks.Add("block", myBlock); 

BlockReference myBr = new BlockReference(1e9, 1e9, 0, "block", 0); 
viewportLayout.Entities.Add(myBr, 0, Color.Red); 
viewportLayout.RemoveJittering = true;

 

See the result below:

Capture.PNG

 

Of course if you have a set of entities, and not just one, that are very far from the origin, the best thing is to compute the center of their bounding box, translate them all of the negative of that quantity and put them in a single block.

Below you can see how to apply this method to the entities read from a dwg file that are positioned very far from the origin:

ReadAutodesk rd =  new ReadAutodesk(@"test.dwg"); 
rd.DoWork(); 
             
// Create a BlockReference  with the content of the dwg (the "myDwg" block with all the entities is automatically added to the viewportLayout.Blocks)             
BlockReference br = rd.CreateXRef("myDwg", new Point3D(0,0,0), viewportLayout); 

// Add the BlockReference to the viewportLayout so that its bounding box is properly computed
viewportLayout.Entities.Add(br); 

// Compute the center of the bounding box 
Point3D boxMid = (br.BoxMin + br.BoxMax)/2;

Block block = viewportLayout.Blocks["myDwg"]; 

// move the entities inside the block back to the origin
foreach (var ent in block.Entities)
{ 
    ent.Translate(-boxMid.X, -boxMid.Y, -boxMid.Z); 
} 

// apply the translation to the blockreference 
br.Translate(boxMid.X, boxMid.Y, boxMid.Z); 

viewportLayout.Entities.Regen(); 

viewportLayout.RemoveJittering = true;
Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.