I have an iPhone 3D model in my SceneKit application, it has a material which I get. It is called iScreen (the image that "is on" the screen of the iPhone):
var iScreen: SCNMaterial!
iScreen = iphone.geometry?.materialWithName("Screen")!
I decided to somehow project a webView there instead of an image.
Therefore I need the frame / position / size of the screen where iScreen "draws" to set the UIWebView's frame. Is that possible?
Note
Of course I tried position, frame, size, etc. but that all was not available :/
you will first have to know to which SCNGeometryElement the material applies (an SCNGeometry is made of one or several SCNGeometryElement).
That geometry element is essentially a list of indices to retrieve vertex data contained in the geometry's SCNGeometrySources. Here you are interested in the position source (it gives you the 3D coordinates of the vertices).
By iterating over these positions you'll be able to find the element's width and height.
Related
I'm trying to create a basic scene an AR.JS with NFT (so it's not just the basic marker-based tracking; it tracks a custom image) using A-frame to place down and position my objects, but I've noticed that e.g.: if I place a 1*1*1 size box in the scene, it will appear at different places on different devices. And also, if I don't scale it up to like 200, it will appear as a very-very tiny box.
E.g.: If I try to view my scene on my phone, the object appears at the exact center of the marker, but if I check it on a different phone, it will appear almost completely outside the marker. Also, if I check it with a webcam, it will appear yet again in a different place, and even in a different size.
I wonder if there is any option to make the marker images bottom left (or any other) corner the 0 0 0 point, so I can position my objects more precisely, and also set the object's width to equal the marker images width, so I don't have to scale up the object like this.
At this moment there is any option to display a model in the center of the NFT marker. This because AR.js depend on jsartoolkit5 and this last has no yet this feature. But if you know the width, height and dpi you can display the object in the center of the maker with this formula (pseudo code):
obj.position.y = (marker.height / marker.dpi * 2.54 * 10)/2.0;
obj.position.x = (marker.width / marker.dpi * 2.54 * 10)/2.0;
You can acquire width, height and dpi while creating your marker or using the dispFeatureSet display app distributed by the Artoolkit5 SDK you can find binaries here https://github.com/artoolkitx/artoolkit5/releases/tag/5.4.0 or from artookitx website https://www.artoolkitx.org/docs/downloads/
I am looking to show some helper text on the GLSurfaceView. But I want to show this only when I see the object in my Camera's frame not before that. How can I detect whether the 3d object is visible in the Camera's frame or not?
Rather than having to check every time what objects are in the camera frame, it might be easier, deepening on your particular application, to simply attach the helper text below or above the object you want it to apply to, on the same anchor.
This would also have the advantage that the text would be centred only when the object is centred - i.e. you would not have the text suddenly fully appear when just a corner of the object is in the camera view.
ViewRenderables allow you to render 'a 2D Android view in 3D space by attaching it to a Node with setRenderable(Renderable)'.
(https://developers.google.com/ar/reference/java/sceneform/reference/com/google/ar/sceneform/rendering/ViewRenderable)
When in picking mode, I want to limit the user from dragging a vertex outside of the defined layout bounds. I've set the ISOMLayout, VisualizationModel, and the VisualizationViewer to be the same size. But if I zoom out (I'm using a CrossoverScalingControl) I can drag vertices way outside the layout/vv's bounds. This results in the scrollbars of my GraphZoomScrollPane not working as expected: there can be vertices floating out there that you can't scroll to and you have to zoom out to see them.
Surely there's a way to lock the user into a certain boundary?
Dimension preferredDimension = new Dimension(1200, 800);
Layout<CNode,CEdge> layout = new ISOMLayout<>(graph);
layout.setSize(preferredDimension);
VisualizationModel<CNode, CEdge> visualizationModel = new DefaultVisualizationModel<>(layout, preferredDimension);
vv = new VisualizationViewer<>(visualizationModel, preferredDimension);
If you want to set a boundary outside which you can't manually move a vertex, you can do that in your code (specifically, in the part that responds to you dragging a selected vertex; you can specify limits there on how far out you can drag a vertex). It's not JUNG's responsibility to prevent you from setting a vertex location to something that the Layout wouldn't use; as far as the JUNG is concerned, you can do that if you want to. :)
I'm hoping to overlay a UIView (specifically a highlight box with some text, etc) over an object rendered in SceneKit, but I'm encountering an issue: I don't know exactly where the object will be onscreen at the time.
Is there a way to get the CGRect frame of a SCNNode's current position within the SCNView? Even just a center point for the node would be helpful, but ideally it would give the whole frame, indicating how much vertical and horizontal space the geometry was taking up onscreen as well.
I've searched in the documentation and online for various references to "frames" and "bounds" relative to an SCNNode, but all I'm finding is stuff about the coordinate system within the scene.
Is there no way of translating a SCNNode's position in a scene into the frame coordinates of the view, or the app window?
Check the post about calculating the projected size of an object.
Performance wise, it is much better to use SpriteKit in SceneKit if you want to overlay 2D contents. Check the overlaySKScene property of SCNSceneRenderer.
I have a GLScene object of varying (but known) size. It is completely surrounded by a TGLDummyCube.
I want to position the GLCamera (with CameraStyle: glPerspective) so that the object is completely visible on screen. I got this running basically - the object is visible, but the distance is sometimes too far, or the object is larger than the screen and clipped.
How can I do that? I suppose that this can be done by a clever combination of camera distance and focal length, but I have not been successful so far.
This seems to be different in GLScene compared to OpenGL. I'm using GLScene and Delphi 2007.
Although varying the camera distance and focal length will change the object's visual size, it has the drawback of also changing the perspective, thus leading to a somewhat distorted view. I suggest to use the camera's SceneScale property instead.
Alas, I have no valid steps to calculate the correct value for that. In my case I have to scale to a cube with varying size, while the window size of the viewer is constant. So I placed two dummycubes at the position of the target cube, each sized to fit either the width or the height of the viewer with appropriate values for SceneScale, camera distance and FocalLength. During runtime I calculate the new SceneScale by the ratio of the target cube size in respect to the dummycube sizes. This works quite well in my case.
Edit: Here is some code I make for the calculations.
ZoomRefX and ZoomRefY are those DummyCubes
TargetDimX and TargetDimY give the size of the current object
DesignWidth and DesignHeight are the size of MyGLView at design time
DesignSceneScale is the camera's SceneScale at design time
The calculation code:
ScaleX := (ZoomRefX.CubeSize*MyGLView.Width)/(DesignWidth*TargetDimX);
ScaleY := (ZoomRefY.CubeSize*MyGLView.Height)/(DesignHeight*TargetDimY);
NewSceneScale := Min(ScaleX, ScaleY)*DesignSceneScale;
The DummyCubes ZoomRefX and ZoomRefY are sized so that they have a small margin to either the left-right or top-bottom edges of the viewing window. The are both positioned so that the front faces match. Also the target object is positioned to match its front face with those of these DummyCubes.
The formulas above allow the window size to be different from design time, but I actually didn't test this feature.
#Andreas if you've been playing with SceneScale (as you mentioned in comments) that means that you are looking for a proper way to fit object within camera view by either changing camera distance/focal length or by resizing object. If so, the easiest way to resize single object to fit the screen is to use its BoundingSphereRadius property like this:
ResizeMultiplier := 2; //play with it, it depends on your camera params
GLFreeForm1.Scale.Scale(ResizeMultiplier / GLFreeForm1.BoundingSphereRadius);
You can add GLDummyCube as root object for all other scene objects and then resize GLDummyCube with method mentioned above.