Redimension the List of SphereVisual3D
#1
How can I redimension the size of the list of spheres but not depending on the spheres' position?
I have an ensemble of 200-300 spheres and I want to redimension them proportionally, in order so that the nodes are the same size visually.
I want all the nodes to have the same dimension indifferent to the node position. In my case, when I zoom the camera with the mouse, many nodes (spheres) will not be seen.
This is the codebase:
// for nodes (list of sphere visual 3d)            
            for (int i = 0; i < nodes.Count; i++)
            {
                try
                {
                    var centerPoint = new Point3D(0, 0, 0);
                    var selectedNodes = nodes.Where(s => s.Radius == 0.51).ToList();
                    if (selectedNodes.Count() == 1)
                    {
                        centerPoint = selectedNodes[0].CenterPosition;
                    }

                    Size worldSize = Camera1.GetWorldSize(new Size(6.2, 2), centerPoint); // not sure how it works (to be investigated)
                    var scaleTransform3D = nodes[i].Transform as ScaleTransform3D; // not sure how it works (to be investigated)

                    scaleTransform3D = new ScaleTransform3D();

                    // To prevent scaling the position (multiplying it with the scale factor), we need to set the center of scale
                    scaleTransform3D.CenterX = nodes[i].CenterPosition.X;
                    scaleTransform3D.CenterY = nodes[i].CenterPosition.Y;
                    scaleTransform3D.CenterZ = nodes[i].CenterPosition.Z;

                    nodes[i].Transform = scaleTransform3D;

                    double scaleFactor = worldSize.Width / 1;
                    scaleTransform3D.ScaleX = scaleFactor;
                    scaleTransform3D.ScaleY = scaleFactor;
                    scaleTransform3D.ScaleZ = scaleFactor;
                }
                catch { }
            }
#2
In you want all the objects in the scene to preserve their site regarding of the distance to the camera, then you can use orthographic camera (camera.CameraType = BaseCamera.CameraTypes.OrthographicCamera).

If you want to use perspective projection but want to preserve the size of only some of the objects, you need to scale those objects so after the projection is applied, the size will remain the same.

This can be done the in the following way:
1) calculate the camera zoom factor:
Code:
var cameraZoomFactor = 1 / Math.Tan(SharpDX.MathUtil.DegreesToRadians((float)Camera1.FieldOfView));
2) get the distance of the object to the camera:
Code:
var cameraPosition = Camera1.GetCameraPosition();
var distance = (objectCenterPosition - cameraPosition).Length;
3) Calculate the per-object zoom factor:
Code:
var objectScaleFactor = distance / cameraZoomFactor;

Use objectScaleFactor in the ScaleTransform3D.


When also using Ab3d.DXEngine, then you can also use object instancing where you specify the object size in screen-space coordinates. This allows rendering millions of meshes (also spheres) with screen-space size. See the "Extreme performance / Screen-space scaled instancing" sample in the Ab3d.DXEngine samples (https://github.com/ab4d/Ab3d.DXEngine.Wpf.Samples)
Andrej Benedik
  


Forum Jump:


Users browsing this thread:
1 Guest(s)