• Login
sketchucation logo sketchucation
  • Login
🤑 SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

Absurd camera behaviour

Scheduled Pinned Locked Moved Developers' Forum
9 Posts 2 Posters 176 Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    Diggsey
    last edited by Diggsey 28 Apr 2012, 19:55

    I have a situation where I need to take control of the camera temporarily, but I'd like to return it to its original position at the end. The API docs show that you can create new instances of the camera class, so I just saved the original camera, did my stuff with the new one and then restored the original camera at the end. The problem is that once a camera has been set as the camera for a view, it actually modifies the old camera instance!

    Example:

    
    cam1 = Sketchup.active_model.active_view.camera
    cam1.perspective = true
    cam2 = Sketchup;;Camera.new
    cam2.perspective = false
    cam1.perspective?                                # outputs true
    cam2.perspective?                                # outputs false
    Sketchup.active_model.active_view.camera = cam2
    cam1.perspective?                                # outputs false
    cam2.perspective?                                # outputs false
    
    

    Seemingly the only way to get this to work is to save all the properties of the curent camera individually at the start and then restore them at the end, but this means the script would break if any new properties are added to the camera class.

    I've also tried using "clone" on the camera which seemed initially to work, but gives the strange error: "Error: #<TypeError: (eval):0:in `perspective?': reference to deleted Camera>" when I try to use it.

    1 Reply Last reply Reply Quote 0
    • D Offline
      Dan Rathbun
      last edited by 28 Apr 2012, 20:01

      cam2 = Sketchup.Camera.new

      is incorrect for 2 reasons:

      1) the class reference is: Sketchup::Camera

      2) The new() constructor has 3 required arguments

      I'm not here much anymore.

      1 Reply Last reply Reply Quote 0
      • D Offline
        Diggsey
        last edited by 28 Apr 2012, 20:05

        The first one is a typo (fixed), and the second one is not true, both the API docs and ruby reflection clearly show that it can be called with no arguments.

        1 Reply Last reply Reply Quote 0
        • D Offline
          Dan Rathbun
          last edited by 28 Apr 2012, 20:07

          @diggsey said:

          I've also tried using " clone" on the camera which seemed initially to work, but gives the strange error: "Error: #<TypeError: (eval):0:in `perspective?': reference to deleted Camera>" when I try to use it.

          clone() and dup() only work for standard Ruby classes (or those API classes that Google specifically overrode, ie, redefined the clone method that is inherited from class Object. [.. And there are only a few or these.])

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • D Offline
            Dan Rathbun
            last edited by 28 Apr 2012, 20:08

            @diggsey said:

            The first one is a typo (fixed), and the second one is not true, both the API docs and ruby reflection clearly show that it can be called with no arguments.

            OK.. so when no args are given, what is eye, target and up ?

            and P.S.: the API docs are full of errors and typos.. and the majority of code samples are erroneous or worthless.

            I'm not here much anymore.

            1 Reply Last reply Reply Quote 0
            • D Offline
              Diggsey
              last edited by 28 Apr 2012, 20:14

              @unknownuser said:

              clone() and dup() only work for standard Ruby classes (or those API classes that Google specifically overrode, ie, redefined the clone method that is inherited from class Object. [.. And there are only a few or these.])

              I realise that, I was just making sure I tried every possibility I could think of.

              @unknownuser said:

              OK.. so when no args are given, what is eye, target and up ?

              It doesn't really matter as long as they are valid (which they are, I've tested it). Either way it's not directly related to the problem, which still occurs in code which does everything "properly" and that code was just the simplest way I could demonstrate it.

              1 Reply Last reply Reply Quote 0
              • D Offline
                Dan Rathbun
                last edited by 28 Apr 2012, 20:24

                @diggsey said:

                ..., so I just saved the original camera, ...

                Example:

                
                > cam1 = Sketchup.active_model.active_view.camera
                > 
                

                No, actually you did not.

                Ruby has ONLY 2 basic things. Objects and References that point at objects.

                It does not really have variables, like BASIC or Pascal.

                So all you did was define a reference cam1 that points at the current view object's camera object.
                Later you made that same camera object's pointer (bypassing your cam1 reference,) point at the cam2 referenced camera object.

                So yes.. you need to save at the minimum the camera object's eye, target and up, in some way. Local references, a hash, an array.. etc.

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • D Offline
                  Diggsey
                  last edited by 28 Apr 2012, 21:41

                  @unknownuser said:

                  Ruby has ONLY 2 basic things. Objects and References that point at objects.

                  It does not really have variables, like BASIC or Pascal.

                  So all you did was define a reference cam1 that points at the current view object's camera object.
                  Later you made that same camera object's pointer (bypassing your cam1 reference,) point at the cam2 referenced camera object.

                  So yes.. you need to save at the minimum the camera object's eye, target and up, in some way. Local references, a hash, an array.. etc.

                  I know how references work, and this strange behaviour is not simply a by-product of that:

                  • First I save a reference to the view's camera
                  • Next I create a NEW camera object, and set the view's camera reference to that object
                  • Now there should be two camera objects in existence, so modifying the properties of one should not affect the properties of the other, but it does.

                  I've tracked it down and the reason for the behaviour is this:

                  • Camera objects start off "empty", and simply store a set of parameters, and don't relate to an actual camera, so you can have many instances of them and change their properties independently.
                  • When a camera object is assigned to a view's camera, the camera object completely changes to become a wrapper around an actual camera - all its parameters are applied to the actual camera and then deleted, and instead the camera object has a pointer to the actual camera, so from now on when you set/get a parameter it goes straight through the wrapper to the actual camera.

                  In reality these two states should be separate classes, the first storing the properties of a camera, and the second wrapping an actual camera in sketchup, with methods to set/get a cameras properties as an object.

                  1 Reply Last reply Reply Quote 0
                  • D Offline
                    Dan Rathbun
                    last edited by 28 Apr 2012, 22:33

                    Ok I played around a bit in the console.. and I agree with you. This is another example of poorly wrapped C++ objects that can cause Rubyist's nightmare.

                    Each time we call Sketchup.active_model.active_view.camera we get a new Ruby object.
                    Ex:

                    Sketchup.active_model.active_view.camera == Sketchup.active_model.active_view.camera %(#008000)[>> false]

                    I'm not here much anymore.

                    1 Reply Last reply Reply Quote 0
                    • 1 / 1
                    1 / 1
                    • First post
                      3/9
                      Last post
                    Buy SketchPlus
                    Buy SUbD
                    Buy WrapR
                    Buy eBook
                    Buy Modelur
                    Buy Vertex Tools
                    Buy SketchCuisine
                    Buy FormFonts

                    Advertisement