3

I want to use orthographic projection to display 3D scene in my app. In my code I put a box in scene and set orthographic projection of Point of view like blow. Camera at (0,0,500) look at -z direction, and box at origin of world. So camera should be able to capture the box.

let cameraNode = SCNNode()
let pov = SCNCamera()
pov.usesOrthographicProjection = true
let width = UISreen.main.bounds.size.width
let glMat = GLKMatrix4MakeOrtho(-width/2, width/2, -width/2, width/2, 1, 1000)
pov.projectionTransform = SCNMatrix4FromGLKMatrix4(glMat)
cameraNode.camera = pov
cameraNode.position = SCNVector3.init(0, 0, 500)
scene.rootNode.addChildNode(cameraNode)

let boxGeo = SCNBox.init(width: 100, height: 100, length: 1, chamferRadius: 0)
let box = SCNNode.init(geometry: boxGeo)
scene.rootNode.addChildNode(box)

But I can see nothing. I find out If set orthographicScale to width/2.0 will works correctly.

pov.orthographicScale = Double(width/2);

Question 1 : I don't know why this works. I read docs of apple but still confused. https://developer.apple.com/documentation/scenekit/scncamera/1436612-orthographicscale?language=objc

orthographicScale

Specifies the camera’s magnification factor when using an orthographic projection.

Why I need magnify orthographic projection? I already set the dimension of it through GLKMatrix4MakeOrtho.

I'm not sure whether it is relate to viewport transform? Because viewport transform in OpenGL computed as follows: https://learn.microsoft.com/en-us/windows/desktop/opengl/glviewport

enter image description here

Question 2 : I also find If I create projection matrix like blow it works same as before.

let glMat = GLKMatrix4MakeOrtho(0, width, 0, width, 1, 1000)

In OpenGL it means different viewing box and will display different partition of scene.

Any help is appreciated!

Community
  • 1
  • 1
ooOlly
  • 1,997
  • 21
  • 31

1 Answers1

0

I suppose, you can't see your 3D objects in the scene using GLKMatrix4MakeOrtho, due to the fact that so many classes of GLKit for iOS and macOS are deprecated now.

In order to see your 3D object, you need to manually set Far Z Clipping parameter in Attributes Inspector. These two fields are near and far clipping planes of the frustum of your Orthographic Camera. A default value of Far=100 doesn't allow you see the scene further than 100 units away.

enter image description here

Then use a Scale property to set a scale factor for your objects in an ortho view.

In order to use it programmatically via GLKMatrix4MakeOrtho, you need to import GLKit and OpenGL modules (as well as all the necessary delegate protocols) into your project at first.

import GLKit
import OpenGL

// Obj-C GLKMatrix4

GLK_INLINE GLKMatrix4 GLKMatrix4MakeOrtho(float left, 
                                          float right,
                                          float bottom, 
                                          float top,
                                          float nearZ, 
                                          float farZ) {
    float ral = right + left;
    float rsl = right - left;
    float tab = top + bottom;
    float tsb = top - bottom;
    float fan = farZ + nearZ;
    float fsn = farZ - nearZ;

    GLKMatrix4 m = { 2.0f / rsl, 0.0f, 0.0f, 0.0f,
                     0.0f, 2.0f / tsb, 0.0f, 0.0f,
                     0.0f, 0.0f, -2.0f / fsn, 0.0f,
                     -ral / rsl, -tab / tsb, -fan / fsn, 1.0f };

    return m;
}

Also, on iOS, GLKit requires an OpenGL ES 2.0 context. In macOS, GLKit requires an OpenGL context that supports the OpenGL 3.2 Core Profile.

But remember! Many GL Features are deprecated, so you'd better use Metal framework. Look at deprecated classes of GLKit.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • Yes I find it will be 100 default. But why I set projectionTransform which already specify zNear and zFar not change the camera z clipping? – ooOlly Sep 23 '18 at 12:41
  • Set it to, at least, `700` at first. Is it working now? Do not apply any math to your Camera. let's just see if it's working now. – Andy Jazz Sep 23 '18 at 12:46
  • 1
    Yes It works. So the zNear and zFar of orthographic projection isn't related to zNear and zFar of camera? – ooOlly Sep 23 '18 at 12:47
  • You mean that you've set programmatically? It's hard to say, I don't see your full project... Why are you using `GLKMatrix4MakeOrtho`? – Andy Jazz Sep 23 '18 at 12:57
  • I want to create a viewing box of orthographic projection that just capture partition of scene. Full projection matrix is created by `GLKMatrix4MakeOrtho`. – ooOlly Sep 23 '18 at 13:00
  • OpenGL is deprecated, but the parts of GLKit being used here are just math. `GLKMatrix4MakeOrtho` is just a shorthand for [math you could do yourself](https://en.wikipedia.org/wiki/Orthographic_projection) which is equally valid regardless of whether you use the resulting matrix with SceneKit, GL, Metal, or whatever else. (Sorry, can’t dive enough into your issue to solve it right now, but at least I can flag what’s *not* the problem.) – rickster Sep 23 '18 at 14:55
  • 1
    Setting zNear and zFar on the camera is part of how the camera calculates its own *perspective* projection matrix. If you’re using ortho projection, clipping distances are part of the matrix you calculate yourself. – rickster Sep 23 '18 at 14:58
  • _“you need to import GLKit and OpenGL modules”_ This is not the problem.  The project would not compile if it were.  If it's not explicitly included, but it's still compiling, Xcode is auto-linking those frameworks for you (the `CLANG_MODULES_AUTOLINK` build setting, by default enabled).  You can't compile/link using functions you aren't linking to, in any IDE/compiler. – Slipp D. Thompson May 17 '20 at 07:20
  • _“due to the fact that so many classes of GLKit for iOS and macOS are deprecated now”_ Also not the issue.  Deprecated does *not* mean broken, disabled, removed, or otherwise— it means “marked for removal in future versions, but for now still works as it always has”.  The proof here is the large number of games on the iOS App Store and on macOS (App Store, Steam, etc.) that still use OpenGL and still work just as well as they always have.  You probably _should_ switch to Metal, but there's no technical reason why OpenGL doesn't work on Apple platforms the same as it always has. – Slipp D. Thompson May 17 '20 at 07:23
  • 1
    @AndyFedoroff Hi, would you be able to take a look on my ARKit related question https://stackoverflow.com/questions/62783206/projecting-the-arkit-face-tracking-3d-mesh-to-2d-image-coordinates ? Thanks for your time!! – swiftlearneer Jul 08 '20 at 19:02
  • 1
    Hi @swiftlearneer! I'm not good at Metal but I'll try. – Andy Jazz Jul 08 '20 at 19:09
  • 1
    Hi @AndyFedoroff! Thanks for your response! I am just wondering my post might be a bit confusing. And I posted the code on GitHub already. So this way might be more understandable for my question: https://github.com/andrewcccc/Ftrack/tree/master/FaceCapturedata-master? – swiftlearneer Jul 09 '20 at 19:47
  • Hi @AndyFedoroff! I am just wondering did you get any progress earlier? I wonder whether you would have some insights to just access the ARKit parameters instead. https://stackoverflow.com/questions/62867707/swift-access-to-arkit-camera-parameters-and-save-them? – swiftlearneer Jul 13 '20 at 14:13
  • 1
    Hi @swiftlearneer, Sorry I am not succeed in what you needed. Almost all of the accessible intrinsic ARCamera parameters are just gettable. The other parameters aren't accessible at all. – Andy Jazz Jul 13 '20 at 15:32
  • @AndyFedoroff, No worries! Thank you so much for your time!! I was planning to get all the parameters so that I can confirm whether those 3D mesh face vertices make sense or not. If you don't mind, do you have a minutes on how to get those intrinsic ARCamera parameters and save them? I only know of this var intrinsics: simd_float3x3 { get }. Should I just print that? Thanks! – swiftlearneer Jul 13 '20 at 15:48
  • https://stackoverflow.com/questions/62623726/what-is-the-real-focal-length-of-the-camera-used-in-realitykit/62627471#62627471 – Andy Jazz Jul 13 '20 at 15:49
  • You can print it this way – `print(sceneView.session.currentFrame?.camera.intrinsics)`. – Andy Jazz Jul 13 '20 at 15:58
  • And look at this post : https://www.hackingwithswift.com/example-code/strings/how-to-save-a-string-to-a-file-on-disk-with-writeto – Andy Jazz Jul 13 '20 at 16:08
  • @AndyFedoroff can you take a look at my question and help me about orthographic camera position? Thanks very much. https://stackoverflow.com/questions/65503089 – Eddie Dec 30 '20 at 06:56